久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Java謎題系列--2

 zxylibrary63 2011-11-03
謎題2:找零時刻
請考慮下面這段話所描述的問題:
Tom在一家汽車配件商店購買了一個價值$1.10的火花塞,,但是他錢包中都是兩美元一張的鈔票,。如果他用一張兩美元的鈔票支付這個火花塞,那么應(yīng)該找給他多少零錢呢,?
下面是一個試圖解決上述問題的程序,,它會打印出什么呢?
public class Change{
public static void main(String args[]){
   System.out.println(2.00 - 1.10);
}
}
你可能會很天真地期望該程序能夠打印出0.90,,但是它如何才能知道你想要打印小數(shù)點(diǎn)后兩位小數(shù)呢,?
如果你對在Double.toString文檔中所設(shè)定的將double類型的值轉(zhuǎn)換為字符串的規(guī)則有所了解,你就會知道該程序打印出來的小數(shù),,是足以將double類型的值與最靠近它的臨近值區(qū)分出來的最短的小數(shù),,它在小數(shù)點(diǎn)之前和之后都至少有一位。因此,,看起來,,該程序應(yīng)該打印0.9是合理的。
這么分析可能顯得很合理,,但是并不正確,。如果你運(yùn)行該程序,你就會發(fā)現(xiàn)它打印的是0.8999999999999999,。
問題在于1.1這個數(shù)字不能被精確表示成為一個double,,因此它被表示成為最接近它的double值,。該程序從2中減去的就是這個值。遺憾的是,,這個計(jì)算的結(jié)果并不是最接近0.9的double值,。表示結(jié)果的double值的最短表示就是你所看到的打印出來的那個可惡的數(shù)字。
更一般地說,,問題在于并不是所有的小數(shù)都可以用二進(jìn)制浮點(diǎn)數(shù)來精確表示的,。
如果你正在用的是JDK 5.0或更新的版本,那么你可能會受其誘惑,,通過使用printf工具來設(shè)置輸出精度的方訂正該程序:
//拙劣的解決方案——仍舊是使用二進(jìn)制浮點(diǎn)數(shù)
System.out.printf("%.2f%n",2.00 - 1.10);
這條語句打印的是正確的結(jié)果,,但是這并不表示它就是對底層問題的通用解決方案:它使用的仍舊是二進(jìn)制浮點(diǎn)數(shù)的double運(yùn)算。浮點(diǎn)運(yùn)算在一個范圍很廣的值域上提供了很好的近似,,但是它通常不能產(chǎn)生精確的結(jié)果,。二進(jìn)制浮點(diǎn)對于貨幣計(jì)算是非常不適合的,因?yàn)樗豢赡軐?.1——或者10的其它任何次負(fù)冪——精確表示為一個長度有限的二進(jìn)制小數(shù)
解決該問題的一種方式是使用某種整數(shù)類型,,例如int或long,,并且以分為單位來執(zhí)行計(jì)算。如果你采納了此路線,,請確保該整數(shù)類型大到足夠表示在程序中你將要用到的所有值,。對這里舉例的謎題來說,int就足夠了,。下面是我們用int類型來以分為單位表示貨幣值后重寫的println語句,。這個版本將打印出正確答案90分:
System.out.println((200 - 110) + "cents");
解決該問題的另一種方式是使用執(zhí)行精確小數(shù)運(yùn)算的BigDecimal。它還可以通過JDBC與SQL DECIMAL類型進(jìn)行互操作,。這里要告誡你一點(diǎn): 一定要用BigDecimal(String)構(gòu)造器,,而千萬不要用BigDecimal(double)。后一個構(gòu)造器將用它的參數(shù)的“精確”值來創(chuàng)建一個實(shí)例:new BigDecimal(.1)將返回一個表示0.100000000000000055511151231257827021181583404541015625的BigDecimal,。通過正確使用BigDecimal,,程序就可以打印出我們所期望的結(jié)果0.90:
import java.math.BigDecimal;
public class Change1{
public static void main(String args[]){
   System.out.println(new BigDecimal("2.00").
   subtract(new BigDecimal("1.10")));
}
}
這個版本并不是十分地完美,因?yàn)镴ava并沒有為BigDecimal提供任何語言上的支持,。使用BigDecimal的計(jì)算很有可能比那些使用原始類型的計(jì)算要慢一些,,對某些大量使用小數(shù)計(jì)算的程序來說,這可能會成為問題,,而對大多數(shù)程序來說,,這顯得一點(diǎn)也不重要。
總之,, 在需要精確答案的地方,,要避免使用float和double;對于貨幣計(jì)算,,要使用int,、long或BigDecimal。對于語言設(shè)計(jì)者來說,,應(yīng)該考慮對小數(shù)運(yùn)算提供語言支持,。一種方式是提供對操作符重載的有限支持,以使得運(yùn)算符可以被塑造為能夠?qū)?shù)值引用類型起作用,,例如BigDecimal,。另一種方式是提供原始的小數(shù)類型,就像COBOL與PL/I所作的一樣,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多