Improper negative number representation

17 visualizzazioni (ultimi 30 giorni)
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 Commenti
Vittorio Picco
Vittorio Picco il 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 il 11 Nov 2020
Floating point numbers! There is lots of matlab documentation on floating point numbers, you just need to search for it.

Accedi per commentare.

Risposta accettata

James Tursa
James Tursa il 11 Nov 2020
Modificato: James Tursa il 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 Commenti
Vittorio Picco
Vittorio Picco il 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 il 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.

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Physics in Help Center e File Exchange

Tag

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by