Improper negative number representation

17 views (last 30 days)
I have encountered a very strange issue. I was having trouble with an if statement that was comparing two numbers. Although the numbers were apparently identical, the equality was seen as false. I dug a little deeper and I found this extremely simple minimal working example. Why is this happening? This doesn't make any sense!
>> format long
>> A = -6*1e-9
A =
-6.000000000000001e-09
  2 Comments
Vittorio Picco
Vittorio Picco on 11 Nov 2020
Interesting discovery, this only happens with some numbers but not others. I am even more confused:
>> -1*1e-9
ans =
-1.000000000000000e-09
>> -2*1e-9
ans =
-2.000000000000000e-09
>> -3*1e-9
ans =
-3.000000000000000e-09
>> -4*1e-9
ans =
-4.000000000000000e-09
>> -5*1e-9
ans =
-5.000000000000000e-09
>> -6*1e-9
ans =
-6.000000000000001e-09
>> -7*1e-9
ans =
-7.000000000000001e-09
>> -8*1e-9
ans =
-8.000000000000000e-09
>> -9*1e-9
ans =
-9.000000000000001e-09
David Hill
David Hill on 11 Nov 2020
Floating point numbers! There is lots of matlab documentation on floating point numbers, you just need to search for it.

Sign in to comment.

Accepted Answer

James Tursa
James Tursa on 11 Nov 2020
Edited: James Tursa on 11 Nov 2020
IEEE double precision floating point cannot represent the number -6e-9 exactly. What you are seeing is the decimal representation of the closest binary floating point bit pattern that IEEE double can represent. This is normal behavior for binary floating point systems. See this link for more discussion:
The "exact" decimal conversion of the binary floating point numbers stored for the numbers in your examples:
>> num2strexact(-1*1e-9)
ans =
'-1.0000000000000000622815914577798564188970686927859787829220294952392578125e-9'
>> num2strexact(-2*1e-9)
ans =
'-2.000000000000000124563182915559712837794137385571957565844058990478515625e-9'
>> num2strexact(-3*1e-9)
ans =
'-3.0000000000000003936399275115964879745433790958486497402191162109375e-9'
>> num2strexact(-4*1e-9)
ans =
'-4.00000000000000024912636583111942567558827477114391513168811798095703125e-9'
>> num2strexact(-5*1e-9)
ans =
'-5.0000000000000001046128041506423633766331704464391805231571197509765625e-9'
>> num2strexact(-6*1e-9)
ans =
'-6.000000000000000787279855023192975949086758191697299480438232421875e-9'
>> num2strexact(-7*1e-9)
ans =
'-7.00000000000000064276629334271591365013165386699256487190723419189453125e-9'
>> num2strexact(-8*1e-9)
ans =
'-8.0000000000000004982527316622388513511765495422878302633762359619140625e-9'
>> num2strexact(-9*1e-9)
ans =
'-9.0000000000000011809197825347894639236301372875459492206573486328125e-9'
  2 Comments
Vittorio Picco
Vittorio Picco on 11 Nov 2020
Thank you very much, makes sense! I'll modify my IF statement from a == b to an abs(a-b)<tolerance
James Tursa
James Tursa on 11 Nov 2020
Good choice. When working with floating point comparisons it is best to use tolerances unless you know for sure that the numbers being compared are exact integers.

Sign in to comment.

More Answers (0)

Categories

Find more on Physics in Help Center and File Exchange

Tags

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!