作者ogamenewbie (._.)
站内java
标题Re: [J2SE] 进行浮点数运算时如何四舍五入至小数第 …
时间Wed Oct 10 15:33:42 2007
※ 引述《archerlin (archer)》之铭言:
: =站内文章=
: 说实在的,我压根不想回应什麽,因为我觉得回应你的人身攻击很没意义
: 就像之前另一位P版主我也只是点到为止,之後再对我的攻击,我也一笑置之不予回应
: 不过很多人都说我人太好,所以有必要出来回一篇解释一些立场...
: : 说实在的, 并不是喜欢拉推文出来打, 而是有些人就是喜欢躲进推文不知道在干麻.
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
: 不知道这句话算不算人身攻击?不过你是球员兼裁判当然你说了算
: 什麽叫"打"?什麽叫"躲"?你的动词实在下的很妙...
: 好好讨论就该就事论事的讨论,为什麽要用这些情绪化的字眼呢?
因为文章前面的数字没有 +1, 这样的回覆你不能满意.
那我道歉, 很抱歉一个"躲"字造成你心情不适.
: 推 ogamenewbie:numberformat?
: 但是你也没有继续说下去说怎麽使用?怎麽做到原PO问的要求...
: 我以我之前遇到这问题的状况,提出我的解决方式,
: 因为我之前就是用DecimalFormat去做,却有时得不到我要的结果,
: 而我後来就是用BigDecimal解决的,所以我提出我的方式而推这句
: 推 archerlin:import java.math.BigDecimal 详见 http://0rz.tw/620Oc 10/09 11:09
: 不过我没有不负责任的推个字就走人,最後还是附了个连结
: 请原PO可以去那里研究,应该就可以想出自己的写法了
这麽说来, 我应该可以为原po可以只看到 NumberFormat
找到 DecimalFormat 而鼓掌了. 抱歉阿, 我这麽不负责任,
原po还能如此上进的找出进一步的资料.
: 後来过了一会儿(10几分钟)我又想这样好像也有点没诚意,
: 所以乾脆写清楚点,提出某一种可以解决的解法,於是就推後面那几行...
: (因为我怕他第一次用没注意会直接用double来建构 BigDecimal,
: 然而就自己经验来说一定要用String这个constructor才能精确计算,
: 这些在API上的英文说明也都有,但我连结都给了故略过这些源由...
: 也就是你後来所谓翻Docs复制英文回的落落长的那篇...)
: 如果说写成method,写成下面这样应该也能run了...
: public static double round(double d, int scale){
: if(scale<0){
: throw new IllegalArgumentException(
: "This scale must be a positive integer or zero!");
: }
: BigDecimal b = new BigDecimal(Double.toString(d));
: return b.divide(new BigDecimal("1"), scale,
: BigDecimal.ROUND_HALF_UP).doubleValue();
: }
: 请注意原po问的方式,他在首篇问的第二三行
: 如果型态是浮点数的话
: 如何对运算结果做四舍五入到特定小数位数
: 这是他的需求,所以我当然input/output都转型回double阿
: 我当然知道如果要做精确点的浮点数运算,通通在BigDecimal里做就好啦!
: 最好是所有运算都用BigDecimal做,最後要输出什麽再看用转型或Format...
: 不然你 System.out.println(0.05+0.01); //也不会是0.06不是吗?
: 这又回到所谓float和double不能够进行精确运算的老问题去了...
: 正因为原PO问的是要一般浮点数的型态,
: 所以我前面才会拿double来toString,最後才会做doubleValue()
: 当然这只是其中一种方法,我知道一定有更快或更好的方法呀!
: 所以我才说类似这样...因为我相信一个问题一定有诸多种方法来解决的!
: 例如後来我再回想我回的东西时,我想到好像也不一定要用除法,
: API里的 setScale(int newScale, RoundingMode roundingMode)
: 应该也能做到类似的事,比如说这样:
: BigDecimal bd = bd.setScale(2, b.ROUND_HALF_UP);
: 方法很多,我知道的方法一定不是最好的...
: 我也只是抛砖引玉、野人献曝一下而已,正因为我觉得我回的不算有内容,
: 所以我才只用推文的方式来回,想说原PO有看到就好了...
: (在我对自己的标准里言之无物的东西我是不会PO成一篇文章的)
: 请问这叫"躲在推文里"吗?本来我也没说你第一行推的有什麽不对不好阿
: 因为你只没头没脑地推一句 numberformat?
: 我觉得你应该有我所不知道的高见,而搞不好根本不需要用到BigDecimal的妙解
: 但你後来又推这两句
: 推 ogamenewbie:如果要用 BigDecimal... 乾脆就不要转回浮点了 XD 10/09 11:30
: 推 ogamenewbie:也不要从浮点转过去.. 10/09 11:31
因为你
====================================================================
: (因为我怕他第一次用没注意会直接用double来建构 BigDecimal,
: 然而就自己经验来说一定要用String这个constructor才能精确计算,
: 这些在API上的英文说明也都有,但我连结都给了故略过这些源由...
====================================================================
: 我当然知道如果要做精确点的浮点数运算,通通在BigDecimal里做就好啦!
: 最好是所有运算都用BigDecimal做,最後要输出什麽再看用转型或Format...
====================================================================
却没有在推文中提出, 我才稍微提一下,
因为我不见得会详读细部资料或者是附注的部分.
所以当初用起来吃了很多苦头.
如果你觉得这是针对你, 我无言.
: 摆明了是针对我嘛...所以激起了我的好奇心,故推
: 推 archerlin:请问O大精确的四舍五入用NumberFormat何解? ^^ 10/09 11:36
: 因为我是真的想知道有没有别的更好的解法,至此我想我也没有口气不好吧?
: 而你有加个 XD 所以我也觉得你态度也很好,而我是真的想知道你的方法...
: : 原po打从一开始就不是使用 BigDecimal, 而是浮点数.
: : 所以我就压根不提 BigDecimal. 因为那很复杂.
: 对呀,正所谓原po打从一开始就是使用浮点数
: 所以我的那个烂方法才会转回浮点数...
: 况且认识或学习使用BigDecimal也不回很复杂吧,
: 如果程式应用上就是需要精确的小数点计算,使用它也是迟早的事阿!
: 如果你写的是买卖东西的系统软体,东西要卖100块的,
: 你给钱时把钱算成 99.99999999999999,程式逻辑也是不会卖你的,不是吗?
NT$ 最低单位应该是一元吧? 好像已经没有五角了.
除非你是处理美元, 否则用 int 应该足够了.
: 况且复不复杂也不是你我能决定的,搞不好原PO有心要学有心要弄懂他的解法呢?
那他就应该再继续提问, 他也如此做了.
: : 原po的回文也有说看不懂a大的说明. (当然也有说看不懂我的说明)
: : 但至少他看了我的说明还知道去挖个叫 DecimalFormat 的东西出来用.
: : (我一开始还只有想到 NumberFormat 咧)
: 我之前遇到这问题时,也是做了像原PO的那实验,
: 一开始我更笨,直接 Math.round(value*100)/100.0 这样来算,
: 後来发现答案有时对有时错,才去想到用DecimalFormat,但又试
: new java.text.DecimalFormat("0.00").format(1.025))
: 也不会得到我预期的1.03而是1.02,我又去论坛寻求答案和翻找API,
: 最後我才知道有BigDecimal这个从来没用过的东西,
: 最後再研究一番,我才将我的问题解决,不只解决了这单一问题,
: 我也得到了更多其他相关的知识,也领略到其他我从来没想过的问题和解决方案
: 而学海无涯,你後来又回的文章内,我还是看不到你当初推 numberformat?时的方法,
: 不管是NumberFormat、DecimalFormat我都还不知道一些正确四舍五入的方法
: (况且我遇过NumberFormat还有看地区格式的问题,例如
: NumberFormat nf = NumberFormat.getInstance();
: NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
: 再去做nf.parse("xxx.xxx")得到的格式也不会是一样的,
: 所以你的程式放到全世界去跑,会因为不同地区对格式的解析而有不同的结果...
: 离题了:P )
: 故我在後面又推这两句
: → archerlin:正因为用DecimalFormat有你说的问题所以我才想请教o大.. 10/09 21:46
: → archerlin:有何单用DecimalFormat可以正确的四舍五入的方式!想学:) 10/09 21:47
: 我也是好声好气,因为我真的想知道你的方法,也是真心想请教你,
: 怕你误会我的意思和语气,最後我还加个笑脸,
: 我不知道冒犯了你什麽,你要说我躲在推文里不出来,我是藏镜人吗 XD
你没有冒犯到我, 我只是单纯看到文章面前数字没有+1, 又被点名到,
所以才会用到"躲"这个词, 造成你如此大的反应, 是我冒犯到你才对.
再次跟你抱歉.
: : 还试出来这个 Rounding 对他来说不合用. 我贴的文章也讲的很清楚.
: : 5.0 使用的是 Rounding to Even, 也有画线说为什麽会舍到那边去.
: 这,我真不知要回什麽(苦笑),API你会看我会看原PO也会看...
: 我要回API人人会看,各有巧妙不同吗? XD
对不起欧, 我就是那种不会全看的人.
: 不是复制贴上画个重点说明,你的本来意思就可以扭曲到这
: 你本来的意思就是压根不想用 BigDecimal,後来又复制一大堆API上的东西
我本来的意思就是不要拿 double 转进去,
请问一下压根不想用 BigDecimal 的词句在哪边?
而且全部改用 BigDecimal 的话.
然後接下来你所有用到一般四则运算符号的地方
全部都要改用 BigDecimal 的运算法.
我觉得那样很复杂, 所以我压根就不讲.
: 这,其中的逻辑真的不是很懂,令我想到逻辑学老师教过我的
: "稻草人"谬论,不要紮一个稻草人来拼命"打"它好吗?
: 况且我从头到尾也没有要跟你对"打"阿,怎麽突然抓我的推文就说要"打"我了...
: 然後还说实在不想打我...这...我要回说:谢谢大王不杀之恩吗? XD
我就只是补充说你不要 double 转进去而已.
原po要是程式换 BigDecimal 作修改的程度是他可以接受的,
他自然会去做, 不劳我操心.
: : 6.0 以後可以自选如同 BigDecimal 中所提到的 Rounding Mode.
: : 真的觉得 DecimalFormat 不好用, 自己继承 NumberFormat 写一个咩.
: 说了半天,我还是没看到你针对原PO的问题,以NumberFormat的解法呀?
: 最後还是叫原PO自己写一个咩!比较起一开始的推文
: 推 ogamenewbie:numberformat? 10/09 09:41
: 推 archerlin:import java.math.BigDecimal 详见 http://0rz.tw/620Oc 10/09 11:09
: 不知道谁比较没有诚意呢?
你比较有诚意
: : 前面还有更高段的用 整数运算 %取位数 等等的.
: : 真的要学就去学那种, 学像我当 API index 有屁用.
: 您是 API index已经很厉害了,多少人想到这种程度都还不能够,
: 我想我认识和钻研过的API连两成都不到吧,我开始学JAVA到现在根本没几个月,
: 我只是想知道大家的意见,激荡各种解法,不用又用这样酸来酸去的口气吧?
这样又酸啦.. 都我的错.
: 例如後面说的E版友的解法也很不错阿,或先乘再%再用if判断4舍5入再除回来,
: 或乾脆把double给toString用字串的indexOf去拆解玩弄字串最後再转回来,
: 先不管效率问题的话本来就很多方式可以达到原PO的解决方案阿!
: 多一点容人的雅量不是很好?还是真的要把PTT的JAVA版搞的像一言堂?
: 只有某特定族群能回问题而不被酸?若真是这样我们也只能摇头叹气而後离开,
: 乖乖窝回去有亲切如Duncan大的Javaworld了...其实也没任何损失,不是吗?
: (不过我根本也不想当程式设计师也不想写程式,只是我觉得JAVA这语言挺美的,
: 以後大概也不会做这行了吧,我一直自觉我是程式白痴(问我周遭朋友都知道),
: 我对code就是很没感觉,会常常觉得自己很笨,抱歉...又离题了XD)
: : --
: : 但是老实讲, Rounding to Even 对我来说本来就不是个问题,
: : 我 double 用一用发现不对, 後来就全部改成用 BigDecimal.
: : 自此我 Java 几乎没用过 double..
: 所以你自己double 用一用发现不对,通通都用 BigDecimal,
: 却一开始又不告诉原PO有这种东西?我在推文里提出来又要打我?
我讲第四遍, 我觉得原po就只是结果呈现修饰, 所以就印象
有个 numberformat 的东西我就说了.
然後呢?
: : --
: : 这让我想到对岸有人说 Java 程式设计师有个里程碑.
: : 这个里程碑叫做"能否自行重新实作 String 类"
: : 类似像这样的文章吧?
: : 请把目标往这边摆.
: : API 读再熟, 你顶多就是很厉害的乐高组合工罢了.
: : 能写出你要的 API, 那才是个乐高设计匠.
: : --
: : 请不要写一个不会动或不能正常运行的 String 类,
: : 然後说你跨过那个里程碑了.
: : --
: 你故意加上 -- 这几行把他变成说明档
: 按回覆时就看不到这几行,我能不能也说"你躲在说明档"里?
你不知道有 (A) 全部回覆这种东西嘛? :)
怕你误会我的意思和语气,最後我还加个笑脸。
: API我根本读不熟,甚至读都没读过,都是遇到某些问题才去里面找解答的,
: 我只是个『头痛医头、脚痛医脚』的庸医罢了,很多东西我根本都不会不懂,
: 例如老实说所谓Structs、Spring、Hibernate我根本到现在还不懂他是啥东西,
: 但其系统从我接手到我离职,至少他还没被我搞挂掉过,
: 也因为如此我没有预设立场,没有成见,任何东西我都可虚心的学习他,
: 并且把他吸收变成自己的一部份。人若心存有定见就不太装的下其他东西了。
既然你对'躲'字这麽有成见, 我在此再次道歉
因为是道歉, 所以没有笑脸.
: 所以你提到的乐高组合工,很抱歉我根本还不够格哩,谢谢你的指教。
: (况且我小时候家里也买不起乐高,我只能玩吃乖乖送的霹雳旋风车 XD)
: 尤其是最後那两句
: : 请不要写一个不会动或不能正常运行的 String 类,
: : 然後说你跨过那个里程碑了.
: 我几时又说我写了一个不会run的String然後说我跨过里程碑了?
: 这句话有意无意是不是又在紮稻草人对我人身攻击阿?
心得文能够有如此的回响真是太令我惊讶了,
我完全没有想到居然会有这种可能性阿,
看来我对於人类的思考臆测等等还是不太了解呢,
今後有可能随口提及的心得会让你有被冒犯的感觉,
在此先跟你, 道个二十年份的歉好了, 诚挚的希望你接受.
: 这样的回文你心里是有比较爽快吗?我真的不知道我是哪里得罪你了,
: 若有请提出来我会真心跟您道歉好吗?
不不不, 照你的文章及你的思路看来,
你实在是非常真诚想要为原po解答问题.
也非常真诚的认为我有意要去得罪你.
只是我跟你说啦. 我没有这个意思啦,
我也不知道为什麽你会这样想.
: PS:我不知道回这篇会不会被两位版主不爽砍文,如果要砍也请先通知我(打好久XD)
: 但我是想尽力解释清楚我的立场了,也希望这版能越来越好,谢谢!
又来一个.
再次重申, 砍文的依据是版规, 不是版主爽不爽.
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 125.232.200.248
1F:推 godfat:我觉得有点酸... 10/10 15:38