If you really want your values in the correct range

Update: Made the statement look more intuitive. Also corrected a rogue closing parenthesis...

The other day I noticed a subtle bug in one of my Java visualization prototypes. I somehow got NaNs everywhere, where there should absolutely be none of them.
The math I am using is correct, so I had to find the place where the NaN was produced.
I would really like it if the whole application just blows up into my face when it tries to calculate something with NaN instead of a usable value, but anyway, I had to trace the NaNs to its origin and after some debugging I found it.

Turns out Math.acos (which I was using) has the following in its javadoc:

If the argument is NaN or its absolute value is greater than 1, then the result is NaN.

Duh. Better if I had read the javadoc before blindly throwing my values at the function, because, it turns out, I was passing a 1.000000000002 at some time, for which I got rewarded with NaN.

So, for a quick fix, I decided to ensure that my values are in the correct range of -1.0 to 1.0.

Instead of writing something horrible like

if (val > 1.0)  
    return 1.0;
if (val < -1.0)  
    return -1.0;

Leo gave me a much simpler and nicer looking solution:

return Math.max(-1.0, Math.min(value, 1.0));  

These kind of floating-point errors are really nasty and I should probably take the time for reading "What Every Computer Scientist Should Know About Floating-Point Arithmetic" (Goldberg, 1991), finally.



I am writing these a-programmers-diary posts, for several reasons (at leats these are the ones to bring me starting this with this post).
The first one is, that I want to use this blog more for some kind of diary while programming. So do not assume that this will always be the best solution I am posting. Normally this is just the one I found working and seemed to me not as a crime against humanity.
Another reason is, that I sometimes think 'Oh, I had this problem before, how do I solve this'. So I can use these posts for some kind of reference.
The third reasons is that maybe someone reads this and finds a better solution or spots any mistakes I am making. If you do so feel free to correct me, I really like to learn. Just contact me via mail or twitter and I will add your suggestions as an update to the post, so it stays with the text of the post and does not get lost like outsourced comments like to do.