Improper negative number representation

3 Ansichten (letzte 30 Tage)
Vittorio Picco
Vittorio Picco am 11 Nov. 2020
Kommentiert: James Tursa am 11 Nov. 2020
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 Kommentare
Vittorio Picco
Vittorio Picco am 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 am 11 Nov. 2020
Floating point numbers! There is lots of matlab documentation on floating point numbers, you just need to search for it.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

James Tursa
James Tursa am 11 Nov. 2020
Bearbeitet: James Tursa am 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 Kommentare
Vittorio Picco
Vittorio Picco am 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 am 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.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Tags

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by