-1

I have a vector that contains non-negative doubles. I want to distinguish the cases when an entry is equal to zero and when an entry is greater than zero.

Is it numerically safe to just check if(a>0.0) or can this cause problems? I have no a-priori lower bound for the non-zero values, except machine precision. Should I create a helper-vector containing integers to mark the zero-values for safe checking?

For better understanding: The entries of the vector are something like weights on a graph, and I figured I don't need the adjacency matrix to keep track of the graph topology.

EDIT: My question is: Can and will 0.0 be exactly represented in doubles?

  • what do you mean by "numerically safe"? – Simon Byrne Sep 03 '15 at 15:28
  • If I assign the value 0.0 to the double variable var, will a subsequent var>0.0 certainly yield false? Will a subsequent var==0.0 certainly yield true? I recall that for almost all floating point numbers, at least the second statement would not be true. – Pascal Engeler Sep 03 '15 at 15:31
  • So, after `double x = 0.0`, why do you think `x == 0.0` might be false? – Yu Hao Sep 03 '15 at 15:37
  • As I stated above, if you replace 0.0 with any random floating point number, the statement would certainly be false as a computer can only represent a finite number of numbers. You don't even need to go to large numbers or take many decimals to produce this. Hence I'm asking what happens for the decimal 0.0. – Pascal Engeler Sep 03 '15 at 15:39
  • I'm not sure if the specific case of `x=0.0;x==0.0` may fail, but usually, to easily and efficiently compare to doubles, you can add a "error" with a very small number, so, instead of x==0.0 (or using a vector like you suggest), you can do `x>0.0-small_number && x<0.0+small_number`, of course, small number should be small enough to not affect your needs – angrykoala Sep 03 '15 at 15:40
  • For my non-negative numbers, the first check will certainly be true. However, I have no a-priori lower bound on my non-zero numbers, so the small_number that doesn't affect my needs would be 0.0. – Pascal Engeler Sep 03 '15 at 15:43
  • There are actually two zeroes, one of them "negative", but they will compare equal to each other. – harold Sep 03 '15 at 15:57

1 Answers1

4

Floating point numbers aren't literally evil. Nor are they designed by stupid people. The one and only issue you need to concern yourself with here, is that of rounding.

A number which is set to zero, will be zero. There would be no reason to design a computational system which did not behave this way.

A number which is set to 0.1 will not be 0.1, because 0.1 is not exactly representable and is therefore rounded to the nearest representable number; see Is floating point math broken? for details. But if you set two variables to 0.1 they will compare equal to each other, because 0.1 is rounded the same way each time. (In fact the rounding happens during compilation; at runtime you're just setting the variable to the pre-rounded value.)

Similarly, a number which is set to 0.1 * 3 - 0.3 may not be equal to zero, because 0.1 was rounded, and then the rounded result was multiplied by 3 and that result was rounded, and so on.

So the issue is not one of representation, but of computation. If you set something to a particular value, that's the value it has. If it got there through a sequence of inexact computations, you can't rely on exact equality.

Community
  • 1
  • 1
Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • Ever since I spent 3 weeks being taught the problems of floating point numbers in computers, I have assumed that the worst possible can and will happen when doing operations as the above. Thanks for giving some boundaries I can safely work in. – Pascal Engeler Sep 05 '15 at 09:08