2013-02-22 24 views
0

为什么这段代码打印2.4099999999999997,而不是仅仅2.41的Java模块操作

public class Main 
{ 
    public static void main(String args[]) 
    { 
     double d = 5.55%3.14; 
     System.out.println(d); 
    } 
} 
+5

[每个计算机科学家应该知道什么关于浮点运算](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)。 – Pshemo 2013-02-22 18:49:48

+2

为什么你们所有人都低估了这一点,你需要深入理解浮点算术才能理解这一点。 – cIph3r 2013-02-22 18:51:38

+3

“浮点数/双精度表示几个字节的实数,它们必须做近似才能做到这一点。 ”。这是基本的计算机科学。 – 2013-02-22 18:54:35

回答

1

的Java double可以有精度的问题。

你为什么不试试BigDecimal

+8

“精度问题”使它听起来像一个错误;这不是问题,它是一个浮点。 – LittleBobbyTables 2013-02-22 18:51:09

+0

而BigDecimal并没有解决这个问题: 'import java.math.BigDecimal; public class main { \t public static void main(String [] args){ \t \t final BigDecimal d = new BigDecimal(5。55); \t \t final BigDecimal APPROXPI = new BigDecimal(3.14); \t \t System.out.println(d.remainder(APPROXPI)); \t \t //2.409999999999999698019337301957421004772186279296875 \t} }' – cIph3r 2013-02-22 19:12:25

+1

@ cIph3r实际上BigDecimal的解决它,但是我们需要用数字的字符串表示构造函数的参数,比如'的BigDecimal( “5.55”)'和'的BigDecimal( “3.14”)'获得准确的价值。看看[这个解释](http://www.youtube.com/watch?feature=player_detailpage&v=wbp-3BJWsU8#t=373s)。 – Pshemo 2013-02-22 20:36:20

2
import java.text.DecimalFormat; 

double d = 5.55%3.14;  
DecimalFormat df = new DecimalFormat("#.##"); 
System.out.println(df.format(d)); 

添加的DecimalFormat

编辑:

您还可以

double d = 5.55%3.14; 
    System.out.printf("%1$.2f", d); 
+1

好,其实这并不能真正解决问题, 十进制格式只是舍不准确了...... 'DecimalFormat的DF =新的DecimalFormat (“##。###################”);' 会显示你.. – cIph3r 2013-02-22 19:03:59

+0

公平地说,在很多情况下,这是一个完全可以接受的解决方案。 – Medo42 2013-02-22 19:08:12

3

的问题不是模运算符,而是浮点数的性质。一个double不能保持5.55,3.14或2.41的精确值,所以你可以得到一个近似的答案。

为了更好地理解这一点,当您仅在纸张上写入空间有限时,尝试写下1/3值作为小数。你最终会得到类似于0.33333的东西,这是实际值的近似值。当你用二进制编写它时,5.55会发生同样的情况 - 它会变成101.10001100110011001100110011...,它会在某处被切断以适应双精度的空间。

1

原因是java不像我们这样做数学。 java使用二进制数字(从Horstmann的大Java书籍的第4章)到计算机,435 = 4 * 10^2 + 3 * 10^1 + 5 * 10^0

它这样做是因为二进制数或0)更容易操作,因为计算机中的开关处于打开或关闭状态(1或0)。

这会导致偶然舍入问题。如果你想迫使它变圆,那么就像使用十进制格式一样,或者如果你只需要显示的值四舍五入,你可以使用String.format或printf