 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`
? Eric Postpischil

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