使用Double的Modulo找出数字的数字有什么问题?

时间:2018-12-01 18:47:04

标签: java double modulo

我试图找到一个整数不能容纳的长整数。它获取用户输入的数字并找到数字,并将其放入一个int数组中。对于较小的数字(例如<10 ^ 10),它似乎可以很好地工作,但是当其接近较大的数字时,最后几个数字似乎不可用。

请看一下我的功能:

static void insertDigits(int[] digits, double number) {
    double num=number;
    int counter=digits(number)-1;
    while(counter>=0) {
        digits[counter]=(int) (num%10);
        num=Math.floor(num/10);
        counter=counter-1;
    }
}

当我输入13256709时,我得到(好): 1.3256709E7 1 1.3256709E7 3 1.3256709E7 2 1.3256709E7 5 1.3256709E7 6 1.3256709E7 7 1.3256709E7 0 1.3256709E7 9 但是,当我输入一个长数字如25768437216701562时,我得到: 2.576843721670156E16 2 2.576843721670156E16 5 2.576843721670156E16 7 2.576843721670156E16 6 2.576843721670156E16 8 2.576843721670156E16 4 2.576843721670156E16 3 2.576843721670156E16 7 2.576843721670156E16 2 2.576843721670156E16 1 2.576843721670156E16 6 2.576843721670156E16 7 2.576843721670156E16 0 2.576843721670156E16 1 2.576843721670156E16 5 2.576843721670156E16 6 2.576843721670156E16 0 如您所见,最后一位数字已关闭。如果部分代码存在其他问题,将很乐意在需要时发送更多代码。我觉得这与模运算符与double时髦有关。感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您的方法无法与double一起使用,因为累积的舍入误差会使您少数位数。要转换双精度而不损失精度,您必须专门使用整数算术。即使用Double.doubleToRawLongBits(d),然后使用IEEE-754格式从那里开始工作。

这是我之前写的一个示例。 https://github.com/OpenHFT/Chronicle-Bytes/blob/master/src/main/java/net/openhft/chronicle/bytes/BytesInternal.java#L1513

  

但是当我输入一个长数字如25768437216701562时,我得到:2.576843721670156E16

这是因为2.576843721670156E16是最接近的可表示值,其后的下一个值为2.5768437216701564E16

您可以在下面的代码中看到这一点,该代码将64位浮点数视为64位长。

System.out.println(Double.doubleToRawLongBits(25768437216701560.0));
System.out.println(Double.doubleToRawLongBits(25768437216701564.0));

打印

4852315308354829086
4852315308354829087

就像这两个long值之间没有长表示法一样,它们之间也没有双精度表示法。