Re: [J2SE] 進行浮點數運算時如何四捨五入至小數第 …

看板java作者 (archer)時間18年前 (2007/10/10 14:21), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串9/17 (看更多)
=站內文章= 說實在的,我壓根不想回應什麼,因為我覺得回應你的人身攻擊很沒意義 就像之前另一位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)
文章代碼(AID): #1736-3it (java)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 9 之 17 篇):
文章代碼(AID): #1736-3it (java)