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

在我的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 - 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
    中。否则你到处都会遇到这样的错误。。。