Double comparison precision and tolerance

37 ビュー (過去 30 日間)
Grainne Shannon
Grainne Shannon 2015 年 5 月 7 日
コメント済み: James Tursa 2015 年 5 月 15 日
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 件のコメント
James Tursa
James Tursa 2015 年 5 月 7 日
"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.

サインインしてコメントする。

採用された回答

Walter Roberson
Walter Roberson 2015 年 5 月 7 日
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 .
  1 件のコメント
Grainne Shannon
Grainne Shannon 2015 年 5 月 8 日
Thanks so much for the info. Really appreciated. Grainne

サインインしてコメントする。

その他の回答 (1 件)

Grainne Shannon
Grainne Shannon 2015 年 5 月 15 日
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 件のコメント
Walter Roberson
Walter Roberson 2015 年 5 月 15 日
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 2015 年 5 月 15 日
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:

サインインしてコメントする。

Community Treasure Hunt

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

Start Hunting!

Translated by