【问题标题】:How to get the numbers after the decimal point? (java) [duplicate]如何获得小数点后的数字? (java) [重复]
【发布时间】:2011-09-04 05:41:03
【问题描述】:
 double d = 4.321562;

有没有一种简单的方法可以从 d 中自行提取 0.321562?我试着在数学课上找,但没有运气。如果这可以在不转换为字符串或强制转换为其他任何内容的情况下完成,那就更好了。

【问题讨论】:

    标签: java math numbers double decimal-point


    【解决方案1】:

    好吧,你可以使用:

    double x = d - Math.floor(d);
    

    请注意,由于二进制浮点的工作方式,它不会准确地为您提供 0.321562,因为原始值不是准确地 4.321562。如果您真的对精确数字感兴趣,您应该改用BigDecimal。

    【讨论】:

    • 不要使用这个,而是进行强制转换:x - (int)x。正数和负数都可以正常转换。否则,Math.floor() 将使用“小于或等于参数的最正(最接近正无穷大)整数值”。示例:-123.25 - (int)(-123.25) 将导致 -0.25,因此您可以决定如何处理符号。 Math.floor() 的使用将给出 `0.75' 的正数
    • @Bagzerg:同意,尽管转换为 long 比转换为 double 更好,以处理 int 范围之外的值。当我有机会时将编辑以提及两者。
    【解决方案2】:

    不使用 Math 获得分数的另一种方法是转换为 long。

    double x = d - (long) d;
    

    当您打印double 时,toString 将执行少量舍入,因此您不会看到任何舍入错误。但是,去掉整数部分,四舍五入就不够了,四舍五入的误差就很明显了。

    解决此问题的方法是自己进行舍入或使用 BigDecimal 来控制舍入。

    double d = 4.321562;
    System.out.println("Double value from toString " + d);
    System.out.println("Exact representation " + new BigDecimal(d));
    double x = d - (long) d;
    System.out.println("Fraction from toString " + x);
    System.out.println("Exact value of fraction " + new BigDecimal(x));
    System.out.printf("Rounded to 6 places %.6f%n", x);
    double x2 = Math.round(x * 1e9) / 1e9;
    System.out.println("After rounding to 9 places toString " + x2);
    System.out.println("After rounding to 9 places, exact value " + new BigDecimal(x2));
    

    打印

    Double value from toString 4.321562
    Exact representation 4.321562000000000125510268844664096832275390625
    Fraction from toString 0.3215620000000001
    Exact value of fraction 0.321562000000000125510268844664096832275390625
    Rounded to 6 places 0.321562
    After rounding to 9 places toString 0.321562
    After rounding to 9 places, exact value 0.32156200000000001448796638214844278991222381591796875
    

    注意:double 的精度有限,如果您不使用适当的舍入,您可能会看到表示问题蔓延。这可能发生在您使用 double esp 数字的任何计算中,这些数字不是 2 的幂的精确和。

    【讨论】:

    • 如果您的数字大于 32,例如 32.59,此系统将失败。 31.59d - (long)31.59 的结果与 32.59d - (long)32.59 不同
    • @Hari 我添加了一条注释,说明使用double对任何数学进行适当舍入的必要性
    【解决方案3】:

    使用模数:

    double d = 3.123 % 1;
    assertEquals(0.123, d,0.000001);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-22
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 1970-01-01
      相关资源
      最近更新 更多