繁体   English   中英

十进制值问题

[英]Decimal value issue

我有一个非常烦人的任务要做,并坚持下去。 所以:我需要写一个 function 来返回小数点后的浮点数的值。 例如:参数为:5.456->,返回值应为:456。

我不能使用字符串(当然这很容易)。

你有什么建议吗?

它需要一些步骤来使用floatdouble等原语来完成。 如果您被允许使用BigDecimal ,这将只是一行代码。

给定double d = 5.456 ;

  • 首先,将浮点数之前的部分剪掉。
    • 这样做int full = (int)d; 这将是 5
    • 从中减去完整: d-full现在只是该点之后的部分,所以.456
  • 现在使用循环将值乘以 10,直到“点之后”部分为 0。

这里的特殊之处在于,当您使用 double 时,您会遇到浮点精度问题。 这意味着d之间的值将是0.4560000000000004 为了解决这个问题,让我们引入一个 epsilon。

完整的代码如下所示:

private static final double EPS = 1e-5;
public static void main(String[] args) {
    double d = 5.456;
    System.out.println(afterDot(d));
}

private static int afterDot(double d) {
    d = getDecimals(d);
    while(getDecimals(d) > EPS){ //decimals will likely never be 0 because of precision, so compare with a really small EPS instead of 0
        d *= 10;
    }
    //cast the result to an int to cut off the double precision issues
    return (int)d;
}

private static double getDecimals(double d) {
    int full = (int) d;
    d = d-full;
    return d;
}

这将打印456 我很确定这可以以某种方式进行优化,但它是一个有效的初稿。

您想要的是余数,乘以 10 直到余数为 0。使用BigDecimal防止出现如下所示的舍入问题:

final BigDecimal input = new BigDecimal("5.456");
BigDecimal x = input.remainder(BigDecimal.ONE);
while (x.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) > 0) {
    x = x.multiply(new BigDecimal(10));
}
System.out.println(x.longValue());

这里有两种不针对浮点异常进行调整的方法。

double s = 5.456;
System.out.println(s%1);

或者

System.out.println(s-(int)s);

都打印

0.4560000000000004

或者使用BigDecimal并调整比例并减去 integer 值。

System.out.println(BigDecimal.valueOf(s)
      .setScale(3)
      .subtract(BigDecimal.valueOf((int)s)));

印刷

.456

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM