LaVOZs

The World’s Largest Online Community for Developers

'; c++ - Floating point determinism when reading text files - LavOzs.Com

I'm writing some code that needs to be deterministic across platforms. To avoid small floating point rounding errors in math, I'm using a fixed precision class based on an integer instead of a float.

However, the code is given plain text configuration files that use decimals like "0.1234" which I'm then converting to the fixed point type.

So my question: will loading a float value from a text file always have the same initial floating point value regardless of system architecture?

Perhaps another way of stating the question: is floating point non-determinism ONLY introduced when you perform math operations on different platforms, but if you're just loading values then all architectures can represent exactly the same set of float values?

IEEE floating points are deterministic.

Many C++ compilers do intermediate results in higher precision than what you ask for. This can cause differences between compilers asto what value is calculated.

Asking for a file to be compiled with strict IEEE eliminates that.

Whatever IO library you are using could guarantee what you want regardless; but you could just read the value as a string, then convert to fixed point yourself to avoid having to enforce compiler flags or rely on your library's guarantee.

It is plausible that some library converting a string formatted like 123.4567 to a float could get a different value than some other library and compiler for some dedimal value. Most won't, but I'm imagining a case where adding 6/1000 is done at higher precision on one compiler, and the difference is enough to cause a rounding difference when finally converted back to a 32 bit float.

As a guess, it would be extremely rare.

And as it is rare, libraries might not even know they have such a bug, and either not document it or document that they are deterministic and be wrong about it for 1 out of billions of cases.

will loading a float value from a text file always have the same initial floating point value regardless of system architecture?

No. Different C++ implementations may use different floating-point formats. It might not be possible for one implementation’s double to represent the same value that another implementation produces for input of “0.1234”.

However, IEEE-754 binary32 and binary64 are widely used for float and double.

However again, C++ implementations vary in quality and might not produce good results when converting decimal input to double.

Converting text input to floating-point and then to fixed-point is feasible given limits on the numbers supported, in both magnitude and precision, but requires knowledge of the formats and skill in dealing with them. Writing your own code to convert directly from decimal text to the fixed-point format may be easier.

is floating point non-determinism ONLY introduced when you perform math operations on different platforms,…

Conversion from decimal numerals in text to binary floating-point is an operation that may have rounding errors.

… but if you're just loading values then all architectures can represent exactly the same set of float values?

No, but many use IEEE-754 binary32 and binary64.

To avoid small floating point rounding errors in math, I'm using a fixed precision class based on an integer instead of a float.

Fixed-point arithmetic is subject to rounding errors too. All finite-size numeric formats are.

Perhaps another way of stating the question: is floating point non-determinism ONLY introduced when you perform math operations on different platforms, but if you're just loading values then all architectures can represent exactly the same set of float values?

How would you convert the string "1234" to the number one thousand, two hundred and thirty four? Aren't you going to have to do some math, like figuring out that the "1" digit is in the thousands place and doing something like:

(1 * 1,000) + (2 * 100) + (3 * 10) + (4 * 1)

So your question is based on a flawed premise. You aren't "loading" anything. You are converting a base 10 representation of a floating-point number into the value it corresponds to. That is a sequence of math operations.

So even if floating point non-determinism is only introduced when you perform math operations, that is what you are doing somewhere under the hood.

Related
Limiting floats to two decimal points
Is floating point math broken?
How can I force division to be floating point? Division keeps rounding down to 0?
How to deal with floating point number precision in JavaScript?
Is floating-point math consistent in C#? Can it be?
Can I use rounding to ensure determinism of atomic floating point operations?
Python 3 Float Decimal Points/Precision
How to perform unittest for floating point outputs? - python
Using rounding to make floating point operations deterministic
Fixed-point instead of floating point