<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 17  文章 - 49  trackbacks - 0
    <2006年9月>
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    1234567

    常用鏈接

    留言簿(1)

    隨筆分類(17)

    隨筆檔案(17)

    相冊

    最新隨筆

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    ?

    2006 913 星期三

    不要用floatdouble來進行精確的小數計算

    ?

    什么?難道它們不就是為了小數計算而生的么?在我看到 effective java item31 的時候,發出了這個孤陋寡聞的疑問。

    ?

    知其然:

    為什么說不能用 float double 來進行精確小數計算呢?

    試試執行這樣的語句:

    System.out.println( 1.03 ? - ?. 42 ); // 答案是0.6100000000000001?!

    System.out.println(
    1.00 ? - ? 9 * . 10 ); // 答案是0.09999999999999995?!

    你會發現結果和你的小學數學課程有沖突。

    ?

    知其所以然

    之所以出現這樣的奇怪答案,是因為 float double 不能精確的表達 0.1 ,或者任何 10 的負 n 次方。他們是設計來進行科學和工程上的計算,提供精確的近似值的。它們在涉及金融方面的計算則是不在行的。因為金融方面要求絕對的精確。

    ?

    解決方法

    BigDecimal int 或者 long

    ?

    ?

    BigDecimal?bd? = ? new ?BigDecimal( " 1.00 " );

    ?

    ?

    把所有牽涉到的小數都以這種方式轉變為 BigDecimal 對象,然后用它提供的方法進行計算。

    你就得到了精確的計算結果,隨之而來有兩個小缺點,一個。。。很顯然,就是比直接用原始類型要麻煩,也不能用 +,-,*,/ 這些直觀的符號了;第二個就是速度會慢一點,如果不是用于大量的循環之中,則不是那么要緊。不過,你也同時得到了一個好處, BigDecimal 類還帶了豐富的舍入方法,也是不錯的。

    如果小數位本身不長,則可以用 int 或者 long 來替代,我想你明白這個方法是什么意思的。在速度必須很快的位置,你又不介意自己看著小數點位,這個還是可用的,但如果數字本身超過了 18 位,就只能用 BigDecimal 了。

    ?

    Wednesday, September 13, 2006

    Don’t use float and double when exact answers are required

    ?

    What? Aren’t calculating decimal are what they are design for? I made such an ignorant question when I first read effective java-item31.

    ?

    The phenomenon:

    Why we can’t use float and double to calculate decimal when exact results are required?

    Try the following statements:

    ?

    System.out.println( 1.03 ? - ?. 42 ); // the?answer?is?0.6100000000000001?!

    System.out.println(
    1.00 ? - ? 9 * . 10 ); // the?answer?is?0.09999999999999995?!

    ?

    You will find the answers are not agree with what you have learned in primary school.

    ?

    The reason:

    It is all because float and double can not represent exactly 0.1, or any other negative power of ten. They are designed for scientific and engineering calculation which demands accurate approximation. And they are ill-suited for monetary calculations.

    ?

    The solution:

    Use BigDecimal, int or long instead.

    ?

    ?

    BigDecimal?bd? = ? new ?BigDecimal( " 1.00 " );

    ?

    ?

    Transfer all decimal numbers involved in the calcution into BigDecimal objects as above, and then use them to calcute for a exact result, following with two disadvantages, the first, obviously, less convenient than using primitive types, all notations like +,-,*,/ can not be applied neither; the second, it will be slower, which can be ignored if it was not used in a heavily repeated loop. But you also get one merit which comes from the fact that BigDecimal carrys quite a lot of rounding methods.

    If the quantity is not big, you can use int or long instead, you surely understand how to implement the idea. In performance critical section, and you don’t mind keeping track the of the decimal point yourself, this is feasible. But you have not choice if the quantity is over 18 digits, only BigDecimal is available.

    posted on 2006-09-13 19:23 Ye Yiliang 閱讀(8727) 評論(4)  編輯  收藏 所屬分類: Java

    FeedBack:
    # re: 不要用float和double來進行精確的小數計算 2006-09-14 00:21 weide
    從寫Dephi的時候就發現了這個問題,尤其在比較大小的時候讓人相當困惑

    然后用C#寫程序的時候,開始全用了Decimal類型,但是這個計算過程也是相當的繁瑣,所有數據在運算之間都得轉成double,因為.net提供的數學函數的參數都是double(或者有不是的,我還沒找到)

    后來又花了很大的功夫全變成double了,慘啊-__-|||

    另外就是如何確定有效位數的問題,如果不做取舍,常常會搞得數據超長,當參與計算的數據多起來的時候,就不知道多少是有效的數據了:(

    樓主可有解決辦法?  回復  更多評論
      
    # re: 不要用float和double來進行精確的小數計算 2006-09-14 08:42 Flyingis
    @weide
    Decimal的構造方法應該可以直接設定有效位數啊。

    關于這個問題,在《Java Puzzlers》上面也有詳細的闡述。  回復  更多評論
      
    # re: 不要用float和double來進行精確的小數計算 2006-09-14 13:06 lgn21st
    《Java Puzzle》上面開篇就提到這個puzzle!  回復  更多評論
      
    # re: 不要用float和double來進行精確的小數計算 2006-09-14 18:54 冰川
    沒錯!
    金融方面的軟件一般都用BigDecimal.  回復  更多評論
      
    主站蜘蛛池模板: 中文字幕第一页亚洲| 亚洲第一成年网站大全亚洲| a色毛片免费视频| 久久亚洲AV成人无码国产| 成人免费的性色视频| 亚洲精品色在线网站| 国产亚洲AV夜间福利香蕉149| 91av视频免费在线观看| 亚洲欧洲无码AV不卡在线| 国产成人精品日本亚洲专区| 久久免费看黄a级毛片| 精品特级一级毛片免费观看| 久久精品7亚洲午夜a| 午夜两性色视频免费网站| 99精品视频在线观看免费| 亚洲情A成黄在线观看动漫软件| 日日噜噜噜噜夜夜爽亚洲精品| 18国产精品白浆在线观看免费| 未满十八私人高清免费影院| 亚洲视频一区二区在线观看| 亚洲?V乱码久久精品蜜桃| 最近免费最新高清中文字幕韩国| 337p日本欧洲亚洲大胆人人| 亚洲午夜精品久久久久久人妖| 四虎影视在线永久免费观看| 120秒男女动态视频免费| 产传媒61国产免费| 国产成人亚洲综合一区| 亚洲2022国产成人精品无码区| 免费看国产精品麻豆| 免费A级毛片无码A∨免费| 亚洲阿v天堂在线2017免费| 亚洲熟女综合色一区二区三区| 亚洲欧洲日韩国产综合在线二区| 亚洲精品456播放| 波多野结衣久久高清免费| 精品女同一区二区三区免费站| 拍拍拍无挡视频免费观看1000| 午夜在线亚洲男人午在线| 中文字幕无码精品亚洲资源网久久| 亚洲欧洲国产日韩精品|