Is it possible in floating point to return 0.0 subtracting two different values?

  • A+
Category:Languages

Due to the floating point "approx" nature, its possible that two different sets of values return the same value.

Example:

#include <iostream>  int main() {     std::cout.precision(100);      double a = 0.5;     double b = 0.5;     double c = 0.49999999999999994;      std::cout << a + b << std::endl; // output "exact" 1.0     std::cout << a + c << std::endl; // output "exact" 1.0 } 

But is it also possible with subtraction? I mean: is there two sets of different values (keeping one value of them) that return 0.0?

i.e. a - b = 0.0 and a - c = 0.0, given some sets of a,b and a,c with b != c??

 


The IEEE-754 standard was deliberately designed so that subtracting two values produces zero if and only if the two values are equal, except that subtracting an infinity from itself produces NaN and/or an exception.

Unfortunately, C++ does not require conformance to IEEE-754, and many C++ implementations use some features of IEEE-754 but do not fully conform.

A not uncommon behavior is to “flush” subnormal results to zero. This is part of a hardware design to avoid the burden of handling subnormal results correctly. If this behavior is in effect, the subtraction of two very small but different numbers can yield zero. (The numbers would have to be near the bottom of the normal range, having some signicand bits in the subnormal range.)

Sometimes systems with this behavior may offer a way of disabling it.

Another behavior to beware of is that C++ does not require floating-point operations to be carried out precisely as written. It allows “excess precision” to be used in intermediate operations and “contractions” of some expressions. For example, a*b - c*d may be computed by using one operation that multiplies a and b and then another that multiplies c and d and subtracts the result from the previously computed a*b. This latter operation acts as if c*d were computed with infinite precision rather than rounded to the nominal floating-point format. In this case, a*b - c*d may produce a non-zero result even though a*b == c*d evaluates to true.

Some C++ implementations offer ways to disable or limit such behavior.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: