Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing floats with Single.Parse()

Here comes a silly question. I'm playing with the parse function of System.Single and it behaves unexpected which might be because I don't really understand floating-point numbers. The MSDN page of System.Single.MaxValue states that the max value is 3.402823e38, in standard form that is

340282300000000000000000000000000000000

If I use this string as an argument for the Parse() method, it will succeed without error, if I change any of the zeros to an arbitrary digit it will still succeed without error (although it seems to ignore them looking at the result). In my understanding, that exceeds the limit, so What am I missing?

like image 542
toplel32 Avatar asked Sep 30 '22 20:09

toplel32


2 Answers

It may be easier to think about this by looking at some lower numbers. All (positive) integers up to 16777216 can be exactly represented in a float. After that point, only every other integer can be represented (up to the next time we hit a limit, at which point it's only every 4th integer that can be represented).

So what has to happen then is the 16777218 has to stand for 16777218∓1, 16777220 has to stand for 16777220∓1, etc. As you move up into even larger numbers, the range of integers that each value has to "represent" grows wider and wider - until the point where 340282300000000000000000000000000000000 represents all numbers in the range 340282300000000000000000000000000000000∓100000000000000000000000000000000, approximately (I've not actually worked out what the right ∓ value is here, but hopefully you get the point)


Number         Significand             Exponent

16777215 =   1 11111111111111111111111     2^0      = 111111111111111111111111
16777216 =   1 00000000000000000000000     2^1      = 1000000000000000000000000
16777218 =   1 00000000000000000000001     2^1      = 1000000000000000000000010
             ^
             |
             Implicit leading bit
like image 64
Damien_The_Unbeliever Avatar answered Oct 03 '22 09:10

Damien_The_Unbeliever


That's actually not true - change the first 0 to 9 and you will see an exception. Actually change it to anything 6 and up and it blows up.

Any other number is just rounded down as float is not an 100% accurate representation of a decimal with 38+1 positions that's fine.

like image 26
Yishai Galatzer Avatar answered Oct 03 '22 08:10

Yishai Galatzer