snakile - 3 years ago 56

Java Question

I have a variable

`x`

`float`

`p`

`x`

`double`

`Math.pow(x, p)`

`x^p`

`float`

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

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 *x*^{p}. 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 24^{th} bit of a significand (counting the most significant bit as the 0^{th} 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 2^{31}, 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 2^{30}.

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**