niedziela, 20 listopada 2016

How not to compare floating point variables

During the introduction of floating point arithmetics my students often see a code like: Such an example is an occasion to explain the binary representation of floating point data and the problems with rounding errors.

Having in mind that floating point is not easy I am not eager to expose freshmen students to such problems specifically during tests and for a given problem:

Given the positive integer number x read from input, please print all numbers from [1..x] which are squares of natural numbers.

I have expected something like: But in one case I got something like (comment is mine): Beside efficiency issues, the above code is of course wrong. But, for some specific compiler, environment and small inputs it looked like working. To be honest, I was probably more surprised with this "correct" behavior than the student who was explained that the code is indeed wrong.

Comparing doubles by "==" operator is not a good idea but after several tests this example showed me that floating point arithmetic is less deterministic I had expected. For example it is not clear how much precision the internal calculations are evaluated at: double or maybe "register precision"? The answer is: "it depends", for more details I am redirecting you to Random ASCII, Floating-Point Determinism by Bruce Dawson and his earlier post: Intermediate Floating-Point Precision.

wtorek, 26 stycznia 2016

Even for simple code follow the rules as usually

The exercise was to write a my_find function in C++ using C style constructions known from standard qsort, bsearch like functions. The suggested prototype was:

void* my_find(void *key, void *array, int element_size, int n);
The key is a key we are about to find in the array of n elements where each element has the size element_size. The function should return the pointer to the element or null pointer if it does not exist. After over one hour, as an effect of a serious effort of one of my fairly good freshmen I got the following buggy code:

The problem is with the ArrayCOPY pointer which makes no progress with the iteration of outer loop in the case of false match.

Instead of correcting the above I would like to give similar code where the inner loop is a separate function thus making the whole thing easier to code:

Conclusion

The idea behind the student's solution was correct from the early beginning. The code seemed to be ready after approximately 15 minutes. Over next 40 minutes unsystematic (and unsuccessful) attempts were made to find and correct bugs. The point is: even if the task seems to be easy and straightforward, you need to keep calm and follow the rules (good programming practices) as usually.