【问题标题】:Java module operator [duplicate]Java模块运算符[重复]
【发布时间】:2013-02-22 18:48:35
【问题描述】:

为什么这段代码打印的是 2.4099999999999997,而不仅仅是 2.41

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

【问题讨论】:

  • 为什么你们都反对这个,你需要对浮点运算有深刻的理解才能理解这个..
  • “float/double 用几个字节表示实数,他们必须做近似值才能做到这一点。”没有什么很深的内容。这是基本的计算机科学。
  • @CyrilleKarmann 好的.. 知道这很容易,理解起来相当困难.. 但是很难完全理解 Pshemo 发布的文章...
  • 我同意链接的文章对于初学者来说很难消化。

标签: java floating-point modulo


【解决方案1】:

问题不在于模运算符,而在于浮点数的性质。双精度数不能包含 5.55、3.14 或 2.41 的精确值,因此您可以得到一个大概的答案。

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

【讨论】:

    【解决方案2】:
    import java.text.DecimalFormat;
    
    double d = 5.55%3.14;       
    DecimalFormat df = new DecimalFormat("#.##");
    System.out.println( df.format( d ));
    

    添加十进制格式

    编辑:

    你也可以

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

    【讨论】:

    • 好吧,实际上这并不能真正解决问题,十进制格式化程序只是将不准确性四舍五入......DecimalFormat df = new DecimalFormat("##.###################"); 会告诉你......
    • 公平地说,在许多情况下这是一个完全可以接受的解决方案。
    【解决方案3】:

    Java double 可能存在精度问题。

    你为什么不试试BigDecimal

    【讨论】:

    • “精度问题”听起来像是一个错误;这不是问题,它是一个浮点数。
    • 而 BigDecimal 不能解决这个问题:import java.math.BigDecimal; public class Main { public static void main(String[] args) { final BigDecimal d = new BigDecimal(5.55); final BigDecimal APPROXPI = new BigDecimal(3.14); System.out.println(d.remainder(APPROXPI)); //2.409999999999999698019337301957421004772186279296875 } }
    • @cIph3r 实际上 BigDecimal 解决了它,但是我们需要在构造函数参数中使用数字的字符串表示形式,例如 BigDecimal("5.55")BigDecimal("3.14") 来获得精确的值。看看this explanation
    • @Pshemo 很好,这行得通:import java.math.BigDecimal; public class Main { public static void main(String[] args) { final BigDecimal d = new BigDecimal("5.55"); final BigDecimal APPROXPI = new BigDecimal("3.14"); System.out.println(d.remainder(APPROXPI)); } } 这绝对有意义
    【解决方案4】:

    原因是 java 不像我们那样做数学。 java使用二进制数(来自Horstmann's big java book的第4章)所以对于计算机,435 = 4 * 10^2 + 3 * 10^1 + 5 * 10^0

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

    这会导致偶尔出现舍入问题。如果你想强制它舍入,然后使用十进制格式,或者如果你只需要舍入显示的值,你可以使用 String.format 或 printf

    【讨论】:

      猜你喜欢
      • 2012-08-23
      • 2011-11-06
      • 2013-09-07
      • 2014-05-10
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 2023-03-29
      • 2011-04-15
      相关资源
      最近更新 更多