The floating point comparison is exact, so 10^-10 is not the same as 0.0.

Basically, you should be comparing against some tolerable difference, say 10^-7 based on the number of decimals you're writing out, that can be accomplished as:

while(fabs(tmp) > 10e-7)
Answer from Mark Elliot on Stack Overflow
Discussions

c++ - float/double equality with exact zero - Stack Overflow
My own two cents are inlining the ... a lot) double result = c / ((abs((b - a)) > 0.00000001f) ? (b - a) : 0.00000001f) ; That expression is, however, ugly as sin. 2013-01-29T08:15:29.977Z+00:00 ... Then all your troubles disappear! The computation of c/(b-a) will never overflow if this test is passed. ... I guess you can use fpclassify(-0.0) == FP_ZERO . But this is only useful if you want to check if someone ... More on stackoverflow.com
🌐 stackoverflow.com
How to check for equality against absolu - C++ Forum
But if a number has to be written out to RAM it is rounded to 64 bits (for a double). So results can vary depending on whether the code can fit intermediate results into the registers or not. Also, when comparing to absolute zero you have the issue of denormalised numbers. More on cplusplus.com
🌐 cplusplus.com
Hot to correctly compare two double values?
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ (also read the rest of the posts in that series when you have a chance) More on reddit.com
🌐 r/C_Programming
6
0
October 28, 2018
c - Checking if a double is equal to -0.00 - Stack Overflow
My problem is that my program is outputing x = -0.00 instead of x = 0.00. I have tried comparing like if(x==-0.00) x=fabs(x) but I've read that it won't work like that with doubles. So my question is are there any other ways to check if double is equal to negative zero? More on stackoverflow.com
🌐 stackoverflow.com
🌐
Ars OpenForum
arstechnica.com › forums › operating systems & software › programmer's symposium
C programming: comparing double with 0.0 | Ars OpenForum
July 8, 2005 - In the current project, I could not possibly introduce it (lots of code to sift through and change) but it sounds intriguing. gmiller, long with assumed decimal is neat, but don't you run into issues when you for example divide two of those values? At some point, you'll have to represent fractions of a certain length, or round off massively, no? hansmuff ... Just do it! . . . And fix it when it doesn't work -- -- Seriously, if you want to check for the original 0.0 value then == is quite ok.
🌐
Bytes
bytes.com › home › forum › topic
How to test a 'float' or 'double' zero numerically? - Post.Byes
September 13, 2008 - To answer your question literally, then comparing to zero is easy, just use if(x==0). However, this usually does not give you much if x is a result of some computation, with this expression you can pretty much just check whether x has been assigned literal zero beforehand.
🌐
Cplusplus
cplusplus.com › forum › beginner › 60595
How to check for equality against absolu - C++ Forum
But if a number has to be written out to RAM it is rounded to 64 bits (for a double). So results can vary depending on whether the code can fit intermediate results into the registers or not. Also, when comparing to absolute zero you have the issue of denormalised numbers.
🌐
Reddit
reddit.com › r/c_programming › hot to correctly compare two double values?
r/C_Programming on Reddit: Hot to correctly compare two double values?
October 28, 2018 -

I'm working on a school project, where I user defines points of a triangle. I then need to calculate, if those points aren't on the same line, so it's possible to form a triangle. Im using something like this:

`double value=(ba1 * (bb2-bc2) + bb1 * (bc2-ba2) + bc1 * (ba2-bb2));`

if (fabs(value)==0){

printf("It's a not triangle\n");

}

 `else{`

printf("It's a triangle\n");

}

But even when I should get the message that it's not a triangle, I don't. How to get over that?

🌐
Oreate AI
oreateai.com › blog › the-tricky-dance-comparing-doubles-to-zero-in-c › 086e1ddbb9fab5d29930b2d7f0c587dc
The Tricky Dance: Comparing Doubles to Zero in C++ - Oreate AI Blog
January 27, 2026 - We introduce a small tolerance, ... Let's say we want to check if a double variable x is effectively zero. We can use the fabs() function from ......
Find elsewhere
🌐
Reddit
reddit.com › r/c_programming › comparing doubles in c
r/C_Programming on Reddit: Comparing doubles in C
July 18, 2016 -

Is it OK to compare doubles in C? Like a == b. Will it give me correct results everytime? If not, workarounds?

What happens when doubles overflow? Does the C state machine go into an undefined state and then your program behavior is undefined/non deterministic? Or does something else happen? How does one prevent this from happening?

🌐
Fitzgibbon
fitzgibbon.ie › floating-point-equality
Is my floating point number equal to zero? - Andrew Fitzgibbon
So using the direct method has an error of 6e-8. For doubles, the direct method has an error of 2.2e-16 compared to the Taylor series at x=0.000279. OK, these are small errors, but since we need some kind of test for x=0 anyway, I don't see why we shouldn't take the opportunity to improve accuracy in this vicinity. And yes, it only costs 2 multiplies which is less than using the sin in those cases.
🌐
Reddit
reddit.com › r/cpp_questions › a few questions about floating point numbers
r/cpp_questions on Reddit: A few questions about floating point numbers
May 25, 2023 -

Before dabbling with graphics I was unaware that there can be issues with comparing floating point numbers and that leads me to ask these questions here:

  1. Should == and != always be avoided when comparing floating point numbers or not and if so should one instead compare using an epsilon or something else?

  2. Are there any issues I need to know about when wanting to sort out unique floating point values either by:

  • using something in <algorithm> in a container or by

  • using containers such as ordered and unordered sets/maps when wanting to use them as a unique key?

Thanks

Top answer
1 of 10
12
Testing floats for equality is fine, but only in the right circumstances. You can test to check if a float is x == 0.0f perfectly fine to ensure that e.g. you're not going to divide by zero. If someone calls your function like f(0.0f) explicitly, then the value of x will be precisely 0.0f. What you don't want to do is expect that any sort of arithmetic results exactly equal any particular number, like checking to see if 0.1f + 0.2f == 0.3f (false). Other than that, you can pretty much just treat floats as real numbers, and whatever you're doing will most likely work. Just be aware that floats can only represent a finite number of sig figs (about 6 or 7 in decimal) so if your values span too great a range, you will have issues with precision. When working with floats, just have an open mind and be ready to look to the floating point arithmetic itself for the source of odd behaviors, and as you run into these issues and read about them you'll develop your understanding of floats. You could actually work some problems by hand and learn them deeply if you really wanted, but personally I just winged it and eventually learned it all as I went. There shouldn't be any surprises with sorting floats, they are ordered just like real numbers. Be aware of the special float values like nan and inf though, they can have special behaviors when it comes to comparisons. I would not recommend using a float as a generic hashmap key under any circumstances, and I'm not sure why you would want to do that. Hashing techniques involving floats require special implementations that STL data structures do not provide.
2 of 10
7
Should == and != always be avoided when comparing floating point numbers or not and if so should one instead compare using an epsilon or something else? I've done graphics, and I don't recall equality comparisons ever really coming up in the first place. You really need a solid understanding ULPS and logarithmic number systems to understand them. I recommend you don't compare floats for equality. Are there any issues I need to know about when wanting to sort out unique floating point values either by: NaN never compares true to anything, even other NaNs. Infinities are not required in C++ (though most implementations support them), you have to check std::numeric_limits::is_iec559. Infinity is not greater than or less than infinity. Denormals are weird and slow. Half the entire number system lies between -1 and +1, after that, the adjacent representable numbers really start to spread out. There is instability in floating point precision - it's very hard to compute the same value twice out of two different but equivalent equations and sets of values. 3 - 2 is likely not equal to 0 + 1. There are positive and negative zeros. This isn't a flaw in the design of floating point numbers, it's to represent limits and from which way they approach zero. Sets make for terrible containers. They're fine if you want to use a set for it's pure mathematical purpose - to test whether or not a value is in the set. If you want a container that's sorted unique, use a vector, sort it, and then disambiguate it with std::unique. Don't use floating points as keys in a map. This is especially true if you are computing the keys - again, the instability of floating point numbers means you'll never compute the exact value twice with different equivalent expressions. Even the same values, the same expression, but you change the order, or you use different temporary values can affect the the results.
🌐
DaniWeb
daniweb.com › programming › threads › 500597 › 0-not-equal-to-0-0000-problem
c++ - 0 not equal to 0.0000 problem | DaniWeb
Avoid casting to int to test for zero; truncation can misclassify small nonzero values. Also compare to 0.0 (double) to make intent clear; the implicit conversion from 0 is not the issue here. References: setprecision only affects formatting, background on why floating-point equality is problematic, and rounding with std::round.
Top answer
1 of 4
3

You can use strtod. Check if the result is zero and subsequently if endptr == nptr, according to the man page:

If no conversion is performed, zero is returned and the value of nptr is stored in the location referenced by endptr.

Something like this:

char input[50];
char * end;
double result = 0;

fgets(input, sizeof input, stdin);

errno = 0;

result = strtod(input, &end);

if(result == 0 && (errno != 0 || end == input)){
    fprintf(stderr, "Error: input is not a valid double\n");
    exit(EXIT_FAILURE);
}

EDIT there seems to be a bit of a discrepancy between the standard and the man page. The man page says that endptr == nptr when no conversion is performed, while the standard seems to imply this isn't necessarily the case. Worse still it says that in case of no conversion errno may be set to EINVAL. Edited the example code to check errno as well.

Alternatively, sscanf could be used (preferred over scanf), in conjunction with fgets:

/* just fgetsed input */
if(sscanf(input, "%lf", &result) != 1){
    fprintf(stderr, "Error: input is not a valid double\n");
    exit(EXIT_FAILURE);
}

Also, don't forget to check the return value of fgets for NULL, in case it failed!

2 of 4
2

Neither simple strtod nor sscanf are enough to distinguish cases such as 1,5 or 1blah from desired 1.0 - All of these will result in 1.0. The reason is that

The strtod(), strtof(), and strtold() functions convert the initial portion of the string pointed to by nptr to double, float, and long double representation, respectively.

To ensure that the entire string was a valid double literal, use strtod like this:

#include <stdlib.h>
#include <errno.h>
#include <stdio.h>

...

char *endptr;
errno = 0;
double result = strtod(input, &endptr);
if (errno != 0 || *endptr != '\0') {
    fprintf(stderr, "the value could not be represented as a double exactly\n");
}

The errno will be set if the value cannot be represented (ERANGE). Additionally, end will be pointing to the first character not converted. If the locale has not been set, when parsing 1,5 or 1blah, endptr will point to the second character. Iff the entire string was successfully parsed as a double constant, *endptr will point to the terminating '\0'.

Note that the errno must be set to zero prior to calling the function, otherwise it will retain the value from a previous failed function call.

🌐
CodePal
codepal.ai › code generator › check double value zero in c++
Check Double Value Zero in C++ - CodePal
August 29, 2023 - @return Returns true if the value is equal to zero, and false otherwise. */ bool isDoubleZero(double val) { // Check if the absolute value of the double value is less than a very small epsilon // to account for floating-point precision errors const double epsilon = 1e-9; return std::abs(val) < epsilon; }
Top answer
1 of 12
207

Assuming 64-bit IEEE double, there is a 52-bit mantissa and 11-bit exponent. Let's break it to bits:

1.0000 00000000 00000000 00000000 00000000 00000000 00000000 × 2^0 = 1

The smallest representable number greater than 1:

1.0000 00000000 00000000 00000000 00000000 00000000 00000001 × 2^0 = 1 + 2^-52

Therefore:

epsilon = (1 + 2^-52) - 1 = 2^-52

Are there any numbers between 0 and epsilon? Plenty... E.g. the minimal positive representable (normal) number is:

1.0000 00000000 00000000 00000000 00000000 00000000 00000000 × 2^-1022 = 2^-1022

In fact there are (1022 - 52 + 1)×2^52 = 4372995238176751616 numbers between 0 and epsilon, which is 47% of all the positive representable numbers...

2 of 12
20

The test certainly is not the same as someValue == 0. The whole idea of floating-point numbers is that they store an exponent and a significand. They therefore represent a value with a certain number of binary significant figures of precision (53 in the case of an IEEE double). The representable values are much more densely packed near 0 than they are near 1.

To use a more familiar decimal system, suppose you store a decimal value "to 4 significant figures" with exponent. Then the next representable value greater than 1 is 1.001 * 10^0, and epsilon is 1.000 * 10^-3. But 1.000 * 10^-4 is also representable, assuming that the exponent can store -4. You can take my word for it that an IEEE double can store exponents less than the exponent of epsilon.

You can't tell from this code alone whether it makes sense or not to use epsilon specifically as the bound, you need to look at the context. It may be that epsilon is a reasonable estimate of the error in the calculation that produced someValue, and it may be that it isn't.

🌐
C-faq
c-faq.com › fp › fpequal.html
Question 14.5
double a, b; ... if(a == b) /* WRONG */ use something like · #include <math.h> if(fabs(a - b) <= epsilon * fabs(a)) where epsilon is a value chosen to set the degree of ``closeness'' (and where you know that a will not be zero).