可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have do to a question to write a method to input an array of type LONG that stores the values of all the powers of 2 from 0 to 63 (i.e. 20 to 263)
Output the contects of the array screen.
Hint: Math.pow(x,y) is ued to put number x to exponent y
so far I have something like
I keep getting error or Math.pow(size,2); required long, found double.
I tried Math.pow(i,2); I get same error./ possible loss of precision ,, any help :) thanks
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);
}
}
}
回答1:
Better shift
For 2x where x ∈ ℕ, you are better off writing this as a bit shift
1L << x
instead of a floating point exponentiation
pow(2, x)
both in terms of precision and in terms of performance. In fact, 1L << x
is so easy to compute that I'd prefer writing that instead of array[x]
, so you might perhaps avoid the array altogether.
More errors?
pow(x, 2)
as you write in your code would be x2 which you could compute more easily as x*x
. So which one is it to be, powers of two or squares?
Furthermore, you write pow(size,2)
which uses size
and does not depend on i
. So all values of your array would be equal. I guess that is not what you meant.
Where your error comes from
The reason of the error message is the fact that the result of Math.pow
is double, and implicit conversion from double
to long
is forbidden in Java. You'd have to write an explicit cast, i.e. (long)pow(2, x)
. But that does round towards zero, so a slight numeric error might cause a wrong result. The only exactness guarantee you have for Math.pow
is this:
The computed result must be within 1 ulp of the exact result.
You could add 0.5
before doing the conversion, or use Math.round
instead of the cast, but as you see, you have to know a lot about the internal workings of floating point math to get this correct. Better to stick to integer math and avoid double
and Math.pow
altogether.
回答2:
The cause of the error is that Math.pow
returns a double
, where you want a long
.
But the whole point of your array is not clear. Whenever you write:
array[i]
you can as well write:
1L << i
and get the same result.
Plus, you will even save the array bounds check.
回答3:
Instead of long[] array = new long[ARRAY_SIZE];
, use double[] array = new double[ARRAY_SIZE];
so that your program looks like:
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:
If you want long
, then convert it, array[i]=(long)Math.pow(size,2);
OR
Covert it to long afterwards by storing it in a temp. array.
回答4:
Ok. First of all Math.pow() returns a double. Your array is of type long. Secondly, you have the parameters for your pow in the wrong order, the first parameter is the base, the second the exponent. Lastly, you are using the wrong variable for your exponent (size is always the same). Lastly be aware that 2^63 is too large to be accurately represented by a double. If you want to use longs, you should use the (Logical) Shift Left operator instead, as others have mentioned.
Here, I fixed it for you:
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);
}
}
}
回答5:
The cause for the actual error message, loss of precision, is that you want, in the argument of pow, to stuff a long integer of 64bit into a double that only can represent integers of 53bit exactly. You get the same message if you want to assign a double value to a float.
Which could be avoided by using type int for the input. For the square to fit into an 64bit signed integer, the argument can not be (much) longer than signed 32bit, and for a power of 2, the exponent has to be smaller than 63.
Or use, for cosa < (1<<26)
,
array[i] = (long)Math.pow((double)cosa,2);