减去数字的两倍和长

时间:2011-08-18 10:51:07

标签: java

在我的JAVA程序中有这样的代码:

int f_part = (int) ((f_num - num) * 100);

f_num是double,num是long。我只想将小数部分取出并将其分配给f_part。但有时候f_part值比它的值小1。这意味着如果f_num = 123.55和num = 123,但f_part等于54.它只发生f_num而num大于100.我不知道为什么会发生这种情况。请有人解释为什么会发生这种情况并纠正它。

5 个答案:

答案 0 :(得分:5)

这是由于双打精度有限。

问题的根源在于文字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来解决它但你必须知道源double实际需要多少小数,或者你可以选择通过double的字符串表示实际上经历了相当复杂的算法


如果您正在使用货币,我强烈建议您

  1. 让价格等由BigDecimal表示,以便您准确地将数字存储为0.1,或
  2. int存储分数(而不是存储双倍数量的美元)。
  3. 这两种方式都完全可以接受并在实践中使用。

答案 1 :(得分:3)

来自The Floating-Point Guide

  

在内部,计算机使用不能的格式(二进制浮点)   准确地表示一个像0.1,0.2或0.3的数字。

     

编译或解释代码时,您的“0.1”已经存在   四舍五入到该格式的最接近的数字,这导致一个小的   甚至在计算发生之前就会出现舍入错误。

看起来你在计算货币价值。 double完全不适合的格式。请改用BigDecimal

答案 2 :(得分:1)

int f_part = (int) Math.round(((f_num - num) * 100));

答案 3 :(得分:0)

这是最常被问及(和回答)的问题之一。浮点算术不能产生精确的结果,因为在64位内部不可能有实数的无穷大。如果您需要任意精度,请使用BigDecimal。

答案 4 :(得分:0)

浮点运算并不像看起来那么简单,并且可能存在精度问题。 有关详细信息,请参阅Why can't decimal numbers be represented exactly in binary?What Every Computer Scientist Should Know About Floating-Point Arithmetic

如果您需要绝对精确,可能需要使用BigDecimal