snakile snakile - 3 years ago 56
Java Question

Raising a float to a certain power in Java

I have a variable

x
of type
float
which should be raised to a certain power
p
. If
x
was a
double
I could have used
Math.pow(x, p)
. Is it possible to calculate
x^p
so that the result will also be a
float
?

Answer Source

Evaluating pow in double and converting to float will almost always produce the same results as evaluating a float implementation of pow. To see this, consider the exact mathematical value of xp. If, using round-to-nearest mode, it is correctly rounded to a double and then correctly rounded to a float, the result is the same as rounding directly to a float unless the rounding to a double moved the value across a boundary where rounding to a float changes.

These boundaries exist only at the midpoints between two representable values, at the 24th bit of a significand (counting the most significant bit as the 0th bit). But the rounding to a double occurs at the 53rd bit. So rounding to double can cause a value to cross the float rounding boundary only if bits 24 to 53 have specific values, shown in the following cases.

[Somebody should check these; it is easy to make a mistake.]

Case 0:

               Bit 23 24 25-52 53 54…
Original            1  0 11…11  1 anything
Rounded to double   1  1 00…00  0 0… (53 above midpoint: rounds up, carries to higher bits)
Then to float       0  0 00…00  0 0… (24 at midpoint, 23 is odd: rounds up, carries into bit 22, not shown)
Directly to float   1  0 00…00  0 0… (24 below midpoint: rounds down)

Case 1:

               Bit 23 24 25-52 53 54…
Original            0  1 00…00  0 anything except all zeroes
Rounded to double   0  1 00…00  0 0… (53 below midpoint: rounds down)
Then to float       0  0 00…00  0 0… (24 at midpoint, 23 is even: rounds down)
Directly to float   1  0 00…00  0 0… (24 above midpoint: rounds up)

Case 2:

               Bit 23 24 25-52 53 54…
Original            0  1 00…00  1 0…
Rounded to double   0  1 00…00  0 0… (53 at midpoint, 52 is even: rounds down)
Then to float       0  0 00…00  0 0… (24 at midpoint, 23 is even: rounds down)
Directly to float   1  0 00…00  0 0… (24 above midpoint: rounds up)

Case requires 31 bits have specific values, so it occurs one time in 231, assuming values are effectively distributed uniformly. Case 1 is the same except it also requires that a one bit occur anywhere in infinitely many bits, the probability of which is effectively one. Case 2 requires infinitely many bits be zero, so it has a probability of zero. Aesthetically at least, cases 1 and 2 dovetail.

The combined probability of any of these cases occurring is 1 in 230.

So, cases where rounding a double result to float produces a different result than directly calculating a float result are rare.

On top of that, most pow implementations are imperfect. They are not known to return correctly rounded results in all cases. (This is hard to implement.) So you may have imperfect results anyway. Rounding to double and then to float will not make a noticeable difference.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download