Specialized asserts for floating point tests
I have a test that looks like:
assert_that(isinf(isect.t));
When this test fails, I get something like this on macOS using Clang 12 installed with MacPorts:
/Users/sfp/LocalWorkspace/jmm/jmm-develop/test/test_bmesh33.c:187: Failure: bmesh33 -> ray_intersects_level_works_on_approximate_sphere
Expected [( sizeof(isect.t) == sizeof(float) ? __inline_isinff((float)(isect.t)) : sizeof(isect.t) == sizeof(double) ? __inline_isinfd((double)(isect.t)) : __inline_isinfl((long double)(isect.t)))] to [be true]
so apparently isinf is implemented using a macro in this case. To avoid this kind of line noise, it might be a good idea to add specialized floating point asserts like:
assert_that_double_is_inf(...);
assert_that_double_is_nan(...);
assert_that_double_is_neginf(...);
assert_that_double_is_finite(...);
etc., with output along the lines of:
Expected [isect.t] to [be inf]
actual value: [-4.3727]
Right. This is a good suggestion. One would wish it was possible to get at the non-preprocessed source, but I assume that is not possible. Or at least not in a portable fashion.
Todo:
- [ ] Create list of asserts (is the suggested list sufficient?)
- [ ] Implement them using tests for them as drivers
- [ ] Document
Judging from these docs, it looks like C99 introduced a number of "comparison and classification" functions. Of these, isfinite, isinf, isnan, and isnormal are the most important. Already covered are isgreater, isgreaterequal, isless, and islessequal (I guess these must have been added to the standard to provide predefined predicates for sorting functions). Not sure what the use case for islessgreater, but I could look into this at some point. That leaves signbit (whether floating point number is negative), and isunordered (whether one or both numbers is NAN). These last two could be good special purpose asserts. But when I get a chance to look at this I will start with the first four.
We could implement them one by one, we don't have to batch them together in implementation. But probably should have all implemented when we release a version with them officially supported though.