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

看板java作者 (._.)時間18年前 (2007/10/10 15:33), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串13/17 (看更多)
※ 引述《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
文章代碼(AID): #17381NJ0 (java)
討論串 (同標題文章)
完整討論串 (本文為第 13 之 17 篇):
文章代碼(AID): #17381NJ0 (java)