Discussion:
[問題] Double*Double
(时间太久无法回复)
aliase
2006-12-04 23:23:51 UTC
Permalink
為甚麼 ....
System.out.println(""+(Double.parseDouble("4.34")*Double.parseDouble("230")));

是 998.19999999999 ??
天阿 ??


--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 210.202.196.65
※ 編輯: aliase 來自: 210.202.196.65 (12/05 15:23)
好累想睡覺
2006-12-05 01:51:02 UTC
Permalink
※ 引述《aliase (aliase)》之銘言:
: 為甚麼 ....
: System.out.println(""+(Double.parseDouble("4.34")*Double.parseDouble("230")));
: 是 998.19999999999 ??
: 天阿 ??
恩恩...感謝您問的問題 上google查了一下文章看到不錯的東西

http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=123&threadID=34521&tstart=240

我從這篇論壇的文章中擷取一些內容來說明

在《Effective Java》這本書中也提到這個原則
float和double只能用來做科學計算或者是工程計算
在商業計算中我們要用java.math.BigDecimal

BigDecimal 的建構子有四個 作者只說了兩個 分別是
BigDecimal(double val) 和 BigDecimal(String val)

在API文件說明中有提到兩者的差異 (我英文不好...不要叫我翻)

Note: the results of this constructor can be somewhat unpredictable. One
might assume that new BigDecimal(.1) is exactly equal to .1, but it is
actually equal to .1000000000000000055511151231257827021181583404541015625.
This is so because .1 cannot be represented exactly as a double (or, for that
matter, as a binary fraction of any finite length). Thus, the long value that
is being passed in to the constructor is not exactly equal to .1, appearances
notwithstanding.

The (String) constructor, on the other hand, is perfectly predictable: new
BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it
is generally recommended that the (String) constructor be used in preference
to this one.

簡單說就是....以String當引數的建構子所回傳出來的數值比較能夠符合我們的預期

因此解決方案就是

如果我們要做一個加法運算,需要先將兩個浮點數轉為String,然後夠造出BigDecimal
在其中一個上使用四則運算方法(add,multiply等....),傳入另一個作為參數
然後把運算的結果(BigDecimal)再轉換為浮點數

最後

來個簡單的範例說明一下 (檔名 A.java)

import java.math.BigDecimal ;
public class A
{
public static void main(String args[])
{
BigDecimal num1 = new BigDecimal("4.34") ;
BigDecimal num2 = new BigDecimal("230") ;
num1 = num1.multiply(num2) ;
System.out.println(num1.doubleValue()) ;
}
}

算出來的數值就是 998.2 了

不過原理我不是很懂啦.... 講了老半天還是只說出實做而已 XD

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 163.25.118.131
※ 編輯: aeifkz 來自: 163.25.118.131 (12/05 17:51)
ing
2006-12-05 02:09:07 UTC
Permalink
�� �ޭz�maeifkz (�n�ַQ��ı)�n���ʨ��G
: �� �ޭz�maliase (aliase)�n���ʨ��G
: ���X�Ӫ��ƭȴN�O 998.2 �F
: ���L���z�ڤ��O�����.... ��F�ѥb���٬O�u���X�갵�Ӥw XD
²�檺���A�q�����Ʀr�t�ΨS���k���T�����ܥX�C�@�Ӽ�

�ҥH�O�Τ@�ӫܱ��񪺼ƨӹG��

�ҥH �o�طL�p���t���N�|�b���o�˪����X�U�Q���{�X��

�ҥH �b�p���ɽЪ`�N���A�y�����t�O....


--
 �H�۷����y�L �|�} ���g���~�ֻ��g ���A  �z�{
���Ǻƨg�����몺�b���� �z�{  ���b�@�i�i�ۤ��W �|�]���b�ߤ�
�L�N�����_ �]�u�İ_�L�����L�� �|�} �O�� �A���O�q�e���A �ڤ]���O�q�e���ڤF
�|�} �ڭ̳Q�~�b�����ҧ��� ���� �Q��i�o�ӥ@��  �z�{ �|�}
�������A�������{ �̥O�ڷP�ʪ�  �z�{ �|�}
 �i amiangel �|�} �z�{  �O�A�����`�B �ڭ̴����L���u�����P

--
�� �o�H��: ���������~�{(ptt.cc)
�� From: 163.22.18.90
aliase
2006-12-05 03:43:54 UTC
Permalink
※ 引述《iFEELing (ing)》之銘言:
: ※ 引述《aeifkz (好累想睡覺)》之銘言:
: : 算出來的數值就是 998.2 了
: : 不過原理我不是很懂啦.... 講了老半天還是只說出實做而已 XD
: 簡單的說,電腦的數字系統沒辦法精確的表示出每一個數
: 所以是用一個很接近的數來逼近
: 所以 這種微小的差異就會在像這樣的場合下被表現出來
: 所以 在計算時請注意型態造成的差別....
的確是這問題... 我只是覺得 一般的 language 應該會 handle
這問題吧...@@... 而不用給上層使用的 progammer 來 handle 吧..@@

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.132.144.221

继续阅读narkive:
Loading...