使用Math.pow在Java中对数字进行平方得到精度错误

Squaring Numbers in java using Math.pow getting error of precision

我有一个问题要写一种方法来输入LONG类型的数组,该数组存储从0到63(即20到263)的所有2的幂的值。

输出提示:使用Math.pow(x,y)将数字x放在指数y

上,到目前为止我遇到类似

之类的东西,但我一直遇到错误或Math.pow(大小,2);需要很长时间,发现两倍。我尝试过Math.pow(i,2);我收到相同的错误。/可能会丢失精度,任何帮助:)谢谢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class ws3q2
{
    public static void main(String[]args)
    {

        int ARRAY_SIZE = 5;

        long size = ARRAY_SIZE;

        long[] array = new long[ARRAY_SIZE];

        for(int i = 0; i < ARRAY_SIZE; ++i)
        {
        array[i] = Math.pow(size,2);
        }

    }
}


更好的shift

对于2x,其中x?∈??,最好将其写为位移

1
1L << x

,而不是浮点指数

1
pow(2, x)

就精度和性能而言。实际上,1L << x是如此容易计算,以至于我宁愿写它而不是array[x],因此您可能会完全避免使用数组。

更多错误?

pow(x, 2)代码是x2,您可以更容易地将其计算为x*x。那么,是2还是平方的幂呢?

此外,您编写的pow(size,2)使用size并且不依赖于i。因此,数组的所有值都将相等。我想这不是您的意思。

错误出自

的地方错误消息的原因是Math.pow的结果是两倍,以及从doublelong的隐式转换在Java中被禁止。您必须编写一个显式强制转换,即(long)pow(2, x)。但这确实趋于零,因此轻微的数字错误可能会导致错误的结果。您对Math.pow的唯一准确性保证是:

The computed result must be within 1 ulp of the exact result.

您可以在进行转换之前添加0.5,或使用Math.round代替强制类型转换,但是如您所见,要深入了解浮点数学的内部工作原理,以使这一方法正确。最好坚持整数数学,并完全避免使用doubleMath.pow


导致实际错误消息的原因是精度下降,这是因为您希望在pow的参数中将64bit的长整数填充为只能精确表示53bit整数的double。如果要为浮点数分配双精度值,则会收到相同的消息。

可以通过将int类型用作输入来避免这种情况。为了使平方适合一个64位有符号整数,该参数不能(远)长于有符号32位,并且对于2的幂,该指数必须小于63。

cosa < (1<<26)

1
array[i] = (long)Math.pow((double)cosa,2);

好的。首先Math.pow()返回一个double。您的数组类型为long。其次,您的战俘参数设置顺序错误,第一个参数是基数,第二个参数是指数。最后,您为指数使用了错误的变量(大小始终相同)。最后,请注意2 ^ 63太大,无法准确地用双精度表示。如要使用多头,应使用(逻辑)左移运算符,如其他人所述。

在这里,我为您修复了它:


而不是long[] array = new long[ARRAY_SIZE];,请使用double[] array = new double[ARRAY_SIZE];,这样您的程序应如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
class ws3q2
{
    public static void main(String[]args)
    {
        int ARRAY_SIZE = 5;
        long size = ARRAY_SIZE;
        double[] array = new double[ARRAY_SIZE];
        for(int i = 0; i < ARRAY_SIZE; ++i)
        {
            array[i] = Math.pow(size,2);
        }
    }
}

EDIT:如果要使用long,则将其转换为array[i]=(long)Math.pow(size,2);,或者将其转换为很长一段时间通过临时存储它。数组。


错误的原因是Math.pow返回double,而您需要long

但是数组的整个点尚不清楚。每当您编写:

1
array[i]

时,您也可以编写:

1
1L << i

并得到相同的结果。

此外,您甚至可以保存数组边界检查。