Java 双倍长数减法
在我的JAVA程序中,有如下代码:Java 双倍长数减法,java,Java,在我的JAVA程序中,有如下代码: int f_part = (int) ((f_num - num) * 100); f_num是double,num是long。我只想把分数部分取出来,分配给f_部分。但有时f_部分的值比它的值小一倍。这意味着如果f_num=123.55和num=123,但f_部分等于54。只有f_num和num大于100。我不知道为什么会这样。请有人解释为什么会发生这种情况,以及如何纠正它。来自: int f_part = (int) Math.round(((f_num
int f_part = (int) ((f_num - num) * 100);
f_num是double,num是long。我只想把分数部分取出来,分配给f_部分。但有时f_部分的值比它的值小一倍。这意味着如果f_num=123.55和num=123,但f_部分等于54。只有f_num和num大于100。我不知道为什么会这样。请有人解释为什么会发生这种情况,以及如何纠正它。来自:
int f_part = (int) Math.round(((f_num - num) * 100));
在内部,计算机使用的格式(二进制浮点)不能
准确地表示一个数字,例如0.1、0.2或0.3
当编译或解释代码时,您的“0.1”已被删除
按该格式四舍五入到最接近的数字,这将导致较小的
甚至在计算之前就存在舍入误差
看起来你在计算金钱的价值double
是完全不适合这种格式的。改用大十进制。来自:
在内部,计算机使用的格式(二进制浮点)不能
准确地表示一个数字,例如0.1、0.2或0.3
当编译或解释代码时,您的“0.1”已被删除
按该格式四舍五入到最接近的数字,这将导致较小的
甚至在计算之前就存在舍入误差
看起来你在计算金钱的价值
double
是完全不适合这种格式的。使用BigDecimal
。这是最常问(和回答)的问题之一。浮点运算不能产生精确的结果,因为在64位内不可能有有限的实数。如果需要任意精度,请使用BigDecimal。这是最常问(和回答)的问题之一。浮点运算不能产生精确的结果,因为在64位内不可能有有限的实数。如果需要任意精度,请使用BigDecimal。这是由于双倍精度有限
问题的根源在于,文本123.55
实际上表示值123.54999…
如果您打印它,它可能看起来像是保存了值123.55
:
System.out.println(123.55); // prints 123.55
但事实上,打印值是一个近似值。这可以通过创建一个BigDecimal
(提供任意精度)并打印BigDecimal来显示:
System.out.println(new BigDecimal(123.55)); // prints 123.54999999999999715...
您可以通过
Math.round
来解决这个问题,但您必须知道源双精度运算实际需要多少位小数,或者您可以选择遍历双精度运算的字符串表示形式,事实上,双精度运算需要相当复杂的算法
如果你在研究货币,我强烈建议你
BigDecimal
表示,它允许您准确地将数字存储为0.1
,或者int
存储美分数(而不是让一个双精度存储美元数)这两种方法都是完全可以接受的,并在实践中使用。这是由于双打的精度有限 问题的根源在于,文本
123.55
实际上表示值123.54999…
如果您打印它,它可能看起来像是保存了值123.55
:
System.out.println(123.55); // prints 123.55
但事实上,打印值是一个近似值。这可以通过创建一个BigDecimal
(提供任意精度)并打印BigDecimal来显示:
System.out.println(new BigDecimal(123.55)); // prints 123.54999999999999715...
您可以通过
Math.round
来解决这个问题,但您必须知道源双精度运算实际需要多少位小数,或者您可以选择遍历双精度运算的字符串表示形式,事实上,双精度运算需要相当复杂的算法
如果你在研究货币,我强烈建议你
BigDecimal
表示,它允许您准确地将数字存储为0.1
,或者int
存储美分数(而不是让一个双精度存储美元数)这两种方法都是完全可以接受的,并在实践中使用。浮点算法并不像看上去那么简单,可能存在精度问题。 有关详细信息,请参见
如果您需要绝对确定的精度,您可能需要使用 浮点运算不像看上去那么简单,可能存在精度问题。 有关详细信息,请参见
如果您需要绝对确定的精度,您可能需要使用 如果
f_num
一开始是双精度的,我看不出使用BigDecimal
会有什么帮助。我只需要前两位小数。是的,你说得对,这是用来计算货币价值的。我刚刚使用了Math.round()方法,它是有效的。谢谢……如果您正在处理价格等问题,我建议您将美分数存储在int
中。否则到处都会遇到这样的错误…如果f_num
是双精度的话,我看不出使用bigdecime
会有什么帮助。我只需要小数点后的前两位。是的,你说得对,这是用来计算货币价值的。我刚刚使用了Math.round()方法,它是有效的。谢谢……如果您正在处理价格等问题,我建议您将美分数存储在int
中。否则你到处都会遇到这样的错误。。。