How to compare approximate values


#1

I need a comparison like the latter which answers “true” instead of false:

48.038385826771666.to_l
~ 1220mm
48.038385826771666.to_l == 1220.mm
false

SketchUp has done some weird things with numbers. Even when you loop them through floats, they don’t lose their approximate-ness:

48.038385826771666.to_l.to_f.to_l
~ 1220mm

They also keep the tilde when they become strings.


#2

When SketchUp compares lengths (numbers of Length class), SketchUp considers its internal tolerance.
This tolerance is important because geometric computations on computers lead to small numerical inaccuracies (rounding, truncation) that accumulate over time and would cause conflicts (coordinates not being planar etc.). SketchUp’s “fix” feature fixes this.

The internal tolerance is neither documented nor part of the API so it might get changed any time.

Best is to keep lengths and numerical values from coordinates/vectors as Length objects without converting to float to_f.


#3

The tilde however does not correspond to the internal tolerance but to the number of digits that you have set in Model Info as display accuracy. The two lengths may truely be different.

You could round them to the same number of digits behind the decimal point (using a helper function by getting from the API the accuracy that is set in Model Info) before doing the comparison.

unit_options = model.options['UnitOptions']
unit_options['LengthUnit']      # >> 4 = meter
unit_options['LengthPrecision'] # >> 2 digits behind decimal

#4

What ‘tolerance’ do you want ?
Let’s assume ±1mm

tol = 1.mm
(48.038385826771666.to_l - 1220.mm).abs <= tol

the second line returns true if within tolerance [in this example ±1mm] or false if outside it…


#5

“Approximate-ness” isn’t some kind of internal state of Length objects. The “~” mark is added when the Length is converted to a String, in the case it’s very close to the numerical representation but not close enough for them to be considered the same using SketchUp’s internal tolerance.

If “48.038385826771666.to_l == 1220.mm” would return true “8.038385826771666.to_l.to_s” would also have to return “1220mm”, not “~ 1220mm”.

For a tolerance larger than the one SketchUp uses internally, use Tig’s solution.

I hope this explanation helps.


#6

Thanks for clarifying everyone. I understand what is going on inside SketchUp better and that helps me to tailor my solution.


#7

This topic was automatically closed after 91 days. New replies are no longer allowed.