Calculate Last Place Device (ULP) for Paired

Does .NET have a built-in method for calculating the ULP of a given double or floating?

If not, which one is most effective?

+6
source share
2 answers

The function seems to be pretty trivial; this is based on the pseudo code in the accepted answer to the question related to volcanino:

double value = whatever; long bits = BitConverter.DoubleToInt64Bits(value); double nextValue = BitConverter.Int64BitsToDouble(bits + 1); double result = nextValue - value; 

For floats, you need to provide your own implementation of SingleToInt32Bits and Int32BitsToSingle , since BitConverter does not have these functions.

This page shows special cases of java function implementation; handling them should also be pretty trivial.

+4
source

The answer to phoog is good, but it has weaknesses with negative numbers, max_double, infinity, and NaN.

phoog_ULP (positive x) -> positive number. Good.
phoog_ULP (negative x) -> negative number. I would expect a positive number.
To fix this, I recommend instead:

 long bits = BitConverter.DoubleToInt64Bits(value) & 0x7FFFFFFFFFFFFFFFL; 

Below are additional cases requiring permission if you need ...

phoog_ULP (x = +/- Max_double 1.797 ... e + 308) returns an infinite result. (+ 1,996 ... e + 292).
phoog_ULP (x = +/- Infinity) leads to NaN. + Expected infinity.
phoog_ULP (x = +/- NaN) may unexpectedly change from sNan to qNaN. No changes are expected. You can argue in any case, if the sign should become + in this case.

To solve this problem, I see only a short series of brutal if () tests to place them, possibly by the value of β€œbits” for expediency. Example:

 double ulpc(double value) { long long bits = BitConverter::DoubleToInt64Bits(value); if ((bits & 0x7FF0000000000000L) == 0x7FF0000000000000L) { // if x is not finite if (bits & 0x000FFFFFFFFFFFFFL) { // if x is a NaN return value; // I did not force the sign bit here with NaNs. } return BitConverter.Int64BitsToDouble(0x7FF0000000000000L); // Positive Infinity; } bits &= 0x7FFFFFFFFFFFFFFFL; // make positive if (bits == 0x7FEFFFFFFFFFFFFL) { // if x == max_double (notice the _E_) return BitConverter.Int64BitsToDouble(bits) - BitConverter.Int64BitsToDouble(bits - 1); } double nextValue = BitConverter.Int64BitsToDouble(bits + 1); double result = nextValue - value; } 
+1
source

Source: https://habr.com/ru/post/909562/


All Articles