Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.
First time visiting? Here are some places to start:- Looking for a certain topic? Check out the categories filter or use Search (upper right).
- Need support? Ask a question to our Community Support category.
- Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
- Be respectful, on topic and if you see a problem, Flag it.
If you would like to contact our Community Manager personally, feel free to send a private message or an email.
Lengths being evaluated as unequal (when they should be equal)
jacob_kingery
Member Posts: 39 EDU
To explore transforms (specifically rotations), I've been working on a Feature that takes in a string and performs the corresponding moves on a (crude) Rubik's Cube model. However, there's something weird going on when I try to isolate the cubies on the back side of the cube. My strategy is to compare certain dimensions of the cubie bounding boxes to the bounding box of the overall cube, and this works for all other sides.
To debug, I have it print out the values it is comparing, followed by the result of the comparison:
The results of this are what are confusing to me. Whenever the values are unequal, it prints
Any ideas as to what might be going on? FS version is 255.0 if that could be relevant.
To debug, I have it print out the values it is comparing, followed by the result of the comparison:
// Cubies on the back if (isIn(side, ['B', 'b'])) { print(bounds.maxY); print(' =?= '); println(maxCorner[1]); println(maxCorner[1] == bounds.maxY); if (maxCorner[1] == bounds.maxY) { cubies = append(cubies, thisCubie); } }
The results of this are what are confusing to me. Whenever the values are unequal, it prints
false
as expected. However, when the values appear to be equal (and should be equal), it sometimes evaluates them as unequal and sometimes as equal.
... 0.0203497 meter =?= 0.00637966 meter false 0.0203497 meter =?= 0.0203497 meter false ... 0.0203497 meter =?= 0.00637966 meter false 0.0203497 meter =?= 0.0203497 meter true ...
Any ideas as to what might be going on? FS version is 255.0 if that could be relevant.
0
Best Answer
-
kevin_o_toole_1 Onshape Employees, Developers, HDM Posts: 565This is a property of floating point math which is not unique to FS.
As a general rule, using a direct equality comparison on floating point numbers is not what you want. Instead, define a tolerance, and check if two numbers are within that tolerance:const tolerance = 0.000001 * meter^3; const volume = evVolume(context, { "entities" : qEverything(EntityType.BODY) }); const expectedVolume = 0.05 * meter^3; if (abs(volume - expectedVolume) > tolerance) { // Do something }
5
Answers
As a general rule, using a direct equality comparison on floating point numbers is not what you want. Instead, define a tolerance, and check if two numbers are within that tolerance:
Looking through the standard library, I found various
tolerantEquals
predicates. Would using those work for catching floating point number issues?On a side note, the
tolerantEquals
predicate inunits.fs
has a precondition, but the documentation states that predicates may not have preconditions. Is the phrase 'may not have' supposed to mean 'sometimes will not have' or 'are not allowed to have'?Regarding preconditions, in this case "may not have" means the documentation is both vague and not correct Will fix.