Re: [J2SE] 進行浮點數運算時如何四捨五入至小數第 …
※ 引述《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
推
10/10 15:38, , 1F
10/10 15:38, 1F
討論串 (同標題文章)
完整討論串 (本文為第 13 之 17 篇):