Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need std::numeric_limits::max_digits10?

I understand that the floating points are represented in memory using sign, exponent and mantissa form which have limited number of bits to represent each part and hence this leads to rounding errors. Essentially, lets say if i have a floating point number, then due to certain number of bits it basically gets mapped to one of the nearest representable form using he rounding strategy.

Does this mean that 2 different floating points can get mapped to same memory representation? If yes, then how can i avoid it programmatically?

I came across this std::numeric_limits<T>::max_digits10

It says the minimum number of digits needed in a floating point number to survive a round trip from float to text to float.

Where does this round trip happens in a c++ program i write. As far as i understand, i have a float f1 which is stored in memory (probably with rounding error) and is read back. I can directly have another float variable f2 in c++ program and then can compare it with original floating point f1. Now my question is when will i need std::numeric_limits::max_digits10 in this use case? Is there any use case which explains that i need to use std::numeric_limits::max_digits10 to ensure that i don't do things wrong.

Can anyone explain the above scenarios?

like image 703
Test Avatar asked Mar 02 '23 09:03

Test


1 Answers

Forget about the exact representation for a minute, and pretend you have a two bit float. Bit 0 is 1/2, and bit 1 is 1/4. Let's say you want to transform this number into a string, such that when the string is parsed, it yields the original number.

Your possible numbers are 0, 1/4, 1/2, 3/4. Clearly you can represent all of them with two digits past the decimal point and get the same number back, since the representation is exact in this case. But can you get away with a single digit?

Assuming half always rounds up, the numbers map to 0, 0.3, 0.5, 0.8. The first and third numbers are exact while the second and fourth are not. So what happens when you try to parse them back?

0.3 - 0.25 < 0.5 - 0.3, and 0.8 - 0.75 < 1 - 0.8. So clearly in both cases the rounding works out. That means you only need one digit past the decimal point to capture the value of our contrived two-bit floats.

You can expand the number of bits from two to 53 (for a double), and add an exponent to alter the scale of the number, but the concept is exactly the same.

like image 148
Mad Physicist Avatar answered Mar 13 '23 05:03

Mad Physicist