Double comparison precision and tolerance

64 views (last 30 days)
I'm using classregtree to analyse tree-structure values. The tree takes double values and compares them like this: if a < b go left else if a >= b go right
I want the comparison operators to use a tolerance of 1e-13 but they're using some smaller tolerance. Having searched the internet and matlab sites I cannot find a) what the tolerance actually is and b) how to change it. Obviously I can write a doubleEqual function and set my own tolerance but I can't replace the above code in classregtree nor can I find a config parameter in the classregtree that will allow me to dictate the tolerance. I cannot use something other than classregtree because this is someone else's code and I can't change it.
I've come across the function digits which looked like the answer but doesn't make a difference to my results. There's a function called optimset which takes a tolerance value but this seems related to mathematical simulations so not what I'm looking for.
To be very specific, I want matlab to evaluate the following values as equal:
-0.0710408977625692 and -0.0710408977625692
Unfortunately it's hard for me to see how these numbers are calculated in the first place but when I diff them I get -1.38777878078145e-17. This number is smaller than my tolerance 1e-13 but matlab considers the first number to be smaller.
Can anyone offer a solution? I would be grateful!
Many thanks Grainne
  1 Comment
James Tursa
James Tursa on 7 May 2015
"digits" affects the number or decimal digits that variable precision arithmetic (vpa) from the Symbolic Toolbox uses. It does not affect regular double arithmetic.
The numbers as posted are exactly the same, so we don't have anything to examine here.
You will need to post some code for us to see what is going on.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 7 May 2015
There is no way to change the tolerance at which MATLAB does double precision comparisons. MATLAB does not do them in software: it uses hardware instructions to do the comparisons, and the hardware instructions work upon the exact bit patterns.
You might be able to tickle MATLAB into do your calculations in single precision instead of double precision. See this previous discussion .

More Answers (1)

Grainne Shannon
Grainne Shannon on 15 May 2015
As follow-up fyi, I have found a solution that suits my needs:
new_value = round(old_value*10^15)./10^15;
This removes significant digits after 15 so my 2 values above: -0.0710408977625692 and -0.0710408977625692 now become -0.071040897762569 and -0.071040897762569 and there are no hidden digits so they evaluate to equal.
I can make these alterations before processing with classregtree so it suits.
Thanks for both of the answers.
  2 Comments
Walter Roberson
Walter Roberson on 15 May 2015
There certainly would be hidden digits.
>> sprintf('%.99g', -0.0710408977625692)
ans =
-0.0710408977625691939739027702671592123806476593017578125
>> sprintf('%.99g', round(-0.0710408977625692*1E15)/1E15)
ans =
-0.071040897762568999684873460864764638245105743408203125
James Tursa
James Tursa on 15 May 2015
FYI, if you are on a Windows system, the underlying code for sprintf is different and you can't use it to print those "hidden" digits. In that case you can use something like num2strexact instead. E.g.,
>> sprintf('%.99g', -0.0710408977625692)
ans =
-0.071040897762569194
>> num2strexact(-0.0710408977625692)
ans =
-7.10408977625691939739027702671592123806476593017578125e-2
>> sprintf('%.99g', round(-0.0710408977625692*1E15)/1E15)
ans =
-0.071040897762569
>> num2strexact(round(-0.0710408977625692*1E15)/1E15)
ans =
-7.1040897762568999684873460864764638245105743408203125e-2
You can find num2strexact here:

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!