作者archerlin (archer)
站内java
标题Re: [J2SE] 进行浮点数运算时如何四舍五入至小数第 …
时间Wed Oct 10 14:21:52 2007
=站内文章=
说实在的,我压根不想回应什麽,因为我觉得回应你的人身攻击很没意义
就像之前另一位P版主我也只是点到为止,之後再对我的攻击,我也一笑置之不予回应
不过很多人都说我人太好,所以有必要出来回一篇解释一些立场...
: 说实在的, 并不是喜欢拉推文出来打, 而是有些人就是喜欢躲进推文不知道在干麻.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
不知道这句话算不算人身攻击?不过你是球员兼裁判当然你说了算
什麽叫"打"?什麽叫"躲"?你的动词实在下的很妙...
好好讨论就该就事论事的讨论,为什麽要用这些情绪化的字眼呢?
请问你一开始不是也"躲在推文不知道在干麻",请溯其本
推 ogamenewbie:numberformat? 10/09 09:41
推 archerlin:import java.math.BigDecimal 详见
http://0rz.tw/620Oc 10/09 11:09
推 archerlin:BigDecimal b = new BigDecimal(Double.toString(d)); 10/09 11:24
→ archerlin:d = b.divide(new BigDecimal("1"), scale, 10/09 11:26
→ archerlin: BigDecimal.ROUND_HALF_UP).doubleValue(); 10/09 11:27
→ archerlin:类似这样...(d为欲四舍五入的double, scale为小数位数) 10/09 11:28
推 ogamenewbie:如果要用 BigDecimal... 乾脆就不要转回浮点了 XD 10/09 11:30
推 ogamenewbie:也不要从浮点转过去..
你不是一开始也只回一串英文字母+问号而已?
还加问号代表你的不确定性,请问这样不负责任的回答算不算"躲在推文"?
推 ogamenewbie:numberformat?
但是你也没有继续说下去说怎麽使用?怎麽做到原PO问的要求...
我以我之前遇到这问题的状况,提出我的解决方式,
因为我之前就是用DecimalFormat去做,却有时得不到我要的结果,
而我後来就是用BigDecimal解决的,所以我提出我的方式而推这句
推 archerlin:import java.math.BigDecimal 详见
http://0rz.tw/620Oc 10/09 11:09
不过我没有不负责任的推个字就走人,最後还是附了个连结
请原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
摆明了是针对我嘛...所以激起了我的好奇心,故推
推 archerlin:请问O大精确的四舍五入用NumberFormat何解? ^^ 10/09 11:36
因为我是真的想知道有没有别的更好的解法,至此我想我也没有口气不好吧?
而你有加个 XD 所以我也觉得你态度也很好,而我是真的想知道你的方法...
: 原po打从一开始就不是使用 BigDecimal, 而是浮点数.
: 所以我就压根不提 BigDecimal. 因为那很复杂.
对呀,正所谓原po打从一开始就是使用浮点数
所以我的那个烂方法才会转回浮点数...
况且认识或学习使用BigDecimal也不回很复杂吧,
如果程式应用上就是需要精确的小数点计算,使用它也是迟早的事阿!
如果你写的是买卖东西的系统软体,东西要卖100块的,
你给钱时把钱算成 99.99999999999999,程式逻辑也是不会卖你的,不是吗?
况且复不复杂也不是你我能决定的,搞不好原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
: 还试出来这个 Rounding 对他来说不合用. 我贴的文章也讲的很清楚.
: 5.0 使用的是 Rounding to Even, 也有画线说为什麽会舍到那边去.
这,我真不知要回什麽(苦笑),API你会看我会看原PO也会看...
我要回API人人会看,各有巧妙不同吗? XD
不是复制贴上画个重点说明,你的本来意思就可以扭曲到这
你本来的意思就是压根不想用 BigDecimal,後来又复制一大堆API上的东西
这,其中的逻辑真的不是很懂,令我想到逻辑学老师教过我的
"稻草人"谬论,不要紮一个稻草人来拼命"打"它好吗?
况且我从头到尾也没有要跟你对"打"阿,怎麽突然抓我的推文就说要"打"我了...
然後还说实在不想打我...这...我要回说:谢谢大王不杀之恩吗? XD
: 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有这种东西?我在推文里提出来又要打我?
: --
: 这让我想到对岸有人说 Java 程式设计师有个里程碑.
: 这个里程碑叫做"能否自行重新实作 String 类"
: 类似像这样的文章吧?
: 请把目标往这边摆.
: API 读再熟, 你顶多就是很厉害的乐高组合工罢了.
: 能写出你要的 API, 那才是个乐高设计匠.
: --
: 请不要写一个不会动或不能正常运行的 String 类,
: 然後说你跨过那个里程碑了.
: --
你故意加上 -- 这几行把他变成说明档
按回覆时就看不到这几行,我能不能也说"你躲在说明档"里?
API我根本读不熟,甚至读都没读过,都是遇到某些问题才去里面找解答的,
我只是个『头痛医头、脚痛医脚』的庸医罢了,很多东西我根本都不会不懂,
例如老实说所谓 Struts、Spring、Hibernate我根本到现在还不懂他是啥东西,
但其系统从我接手到我离职,至少他还没被我搞挂掉过,
也因为如此我没有预设立场,没有成见,任何东西我都可虚心的学习他,
并且把他吸收变成自己的一部份。人若心存有定见就不太装的下其他东西了。
所以你提到的乐高组合工,很抱歉我根本还不够格哩,谢谢你的指教。
(况且我小时候家里也买不起乐高,我只能玩吃乖乖送的霹雳旋风车 XD)
尤其是最後那两句
: 请不要写一个不会动或不能正常运行的 String 类,
: 然後说你跨过那个里程碑了.
我几时又说我写了一个不会run的String然後说我跨过里程碑了?
这句话有意无意是不是又在紮稻草人对我人身攻击阿?
这样的回文你心里是有比较爽快吗?我真的不知道我是哪里得罪你了,
若有请提出来我会真心跟您道歉好吗?
PS:我不知道回这篇会不会被两位版主不爽砍文,如果要砍也请先通知我(打好久XD)
但我是想尽力解释清楚我的立场了,也希望这版能越来越好,谢谢!
--
※ 发信站: 批踢踢实业坊(ptt.cc)
※ 编辑: archerlin 来自: 219.86.32.28 (10/10 15:31)