使用Math.pow在java中使用Squaring Numbers获得精度误差

时间:2014-03-07 14:17:49

标签: java math pow exponentiation

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

输出阵列屏幕的比赛。 提示:Math.pow(x,y)用于将数字x表示为指数y

到目前为止,我有类似

的内容

我一直收到错误或Math.pow(size,2);需要很长时间,发现双倍。 我试过Math.pow(i,2);我得到同样的错误./可能失去精确度,任何帮助:)谢谢

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);
        }

    }
}

5 个答案:

答案 0 :(得分:2)

更好的转变

对于2 x 其中 x ∈ℕ,你最好把它写成一个位移

1L << x

而不是浮点指数

pow(2, x)

在精度和性能方面。实际上,1L << x很容易计算,我更愿意编写而不是array[x],所以你可能完全避免使用数组。

更多错误?

在您的代码中编写

pow(x, 2)将是 x 2 ,您可以更轻松地计算x*x。那么它是哪一个,两个或正方形的权力?

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

您的错误来自

错误消息的原因是Math.pow的结果是双倍的,并且在Java中禁止从doublelong的隐式转换。你必须写一个明确的演员,即(long)pow(2, x)。但这确实会向零舍入,因此轻微的数字错误可能会导致错误的结果。您对Math.pow的唯一准确性保证是这样的:

  

计算结果必须在精确结果的1 ulp范围内。

您可以在进行转化之前添加0.5,或使用Math.round代替演员,但正如您所见,您必须了解很多有关内部工作的内容浮点数学得到这个正确。最好坚持整数数学并完全避免doubleMath.pow

答案 1 :(得分:0)

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

但你阵列的重点还不清楚。每当你写:

array[i]

你也可以写:

1L << i

并获得相同的结果。

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

答案 2 :(得分:0)

使用long[] array = new long[ARRAY_SIZE];代替double[] array = new double[ARRAY_SIZE];,以便您的程序如下:

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);
        }
    }
}

编辑: 如果您需要long,请将其转换为array[i]=(long)Math.pow(size,2); 要么 通过将其存储在临时温度中将其转换为很久。阵列。

答案 3 :(得分:0)

确定。首先,Math.pow()返回一个double。您的数组类型为long。其次,你有错误顺序的pow的参数,第一个参数是基数,第二个参数是指数。最后,您为指数使用了错误的变量(大小始终相同)。最后要注意2 ^ 63太大而无法用双精确表示。如果你想使用longs,你应该使用(Logical)Shift Left操作符,正如其他人提到的那样。

在这里,我为你解决了这个问题:

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(2, i);
        }
    }
}

答案 4 :(得分:0)

实际错误消息的原因,丢失的精度,是你想要在pow的参数中将64bit的长整数填充到一个只能代表53bit的整数的double中究竟。如果要为浮点值指定double值,则会收到相同的消息。

通过使用int类型输入可以避免这种情况。为了使方形适合64位有符号整数,参数不能(多)长于有符号的32位,而对于2的幂,指数必须小于63。

或者使用,cosa < (1<<26)

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