I am writing a program in which there are some operations being performed on a floating point number. After I debugged the program, I came to know that for a particular test case, the value of the variable equals -2.38418579e-07. Now I have cout precision set to 2 digits after decimal. So when I print it, it prints it as -0.00.
However, I would like the output to be 0.00 instead of -0.00. I have tried various if conditions on the variable's value. However, they do not help. Can anyone suggest how to get rid of -0.00 in C++
Firstly, you should define a tolerance number as threshold, where the absolute value of any floating point number bellow this threshold would be considered as zero. For example you could define this threshold as:
#define zero 1e-6
Then you could use the following construct to "filter" your floating point numbers:
template<typename T>
std::enable_if_t<std::is_floating_point<T>::value, T> sanitize(T &&num) {
return std::abs(num) < zero? T{} : num;
}
Live Demo
Notice that I use SFINAE in order for the sanitize function to accepts as input only floating point numbers.
I would like the output to be 0.00 instead of -0.00
I like the other answers better. But in a crunch you can always use brute force ... (are you sure you can ignore the actual results?)
std::string rslt;
{
std::stringstream ss;
ss << variable; // use same formatting as in your example
size_t minusSignIndx = ss.str().find("-0.00");
if (minusSignIndx != std::string::npos)
rslt = " 0.00"; // found the nasty, ignore it
else
rslt = ss.str(); // not nasty, use it
}
//... use rslt
The problem is that every floating point in a certain interval [ low , -0.0] will be printed "-0.00".
Thus you have to find low:
such that print(predecessor(low)) => "-0.01"
such that print(low) => "-0.00"
Then, you'll be able to write something like (nan apart...)
double filter(double x) {
double low = ... ;
return (x < low)
? x
: ((x > 0.0)
? x
: 0.0) ;
}
If you have a correctly rounded printf, and manage your arithmetic to be strictly IEEE754 conformant with appropriate compiler flags, the exact value of low is the nearest double to -1/200, greater than -1/200 (I write 1/200 rather than -0.005 because I'm speaking of the decimal value, not the double)
What we have with correctly rounded sscanf("-0.005","%lf",d): the double result is smaller than -1/200. I did check that with exact arithmetic like for example found in Pharo Smalltalk language:
[-0.005 < (-1/200) and: [-0.005 successor > (-1/200)]] assert.
Its successor is greater than -1/200 (necessarily, above check is just foolproofing).
Thus you can write (notice the <= low):
double filter(double x) {
double low = 0.005 ;
return (x <= low)
? x
: ((x > 0.0)
? x
: 0.0) ;
}
Related
I'm writing a full double to float function for the Arduino (irrelevant, but I couldn't find any "proper" ones) and I do this check:
if (d < 0) {
d *= -1;
bin += "-";
}
I know because of floating point imprecisions double equality is finicky. So is it safe to do that? Or should I stick to this (which I use in later parts of my code anyways)
int compareNums(double x, double y) {
if (abs(x - y) <= EPSILON) {
return 0;
} else if (x > y) {
return 1;
} else {
return -1;
}
}
And a couple quick questions: does it matter if I do d < 0 or d < 0.0?
I'm multiplying a double d by 10 until it has no fractional part, so I do a check similar to d == (int) d. I'm wondering what's a good epsilon to use (I used this here http://msdn.microsoft.com/en-us/library/6x7575x3(v=vs.80).aspx), since I don't want to end up with an infinite loop. According to the article 0.000000119209 is the smallest distinguishable difference for floats or something like that.
Thanks
d < 0 is valid (though I'd prefer to write d < 0.0. In the first case the zero will be "promoted" to double before the comparison.
And comparing double to zero with < or > is perfectly valid, and does not require an "epsilon".
bin += "-"; is nonsensical.
In general comparing floats/doubles with "==" is invalid and should never be done (except for some special cases such as checking for zero or infinity). Some languages do not even allow "==" (or equivalent) between floats.
d == (int) d is more nonsense.
See my answer to this question:
How dangerous is it to compare floating point values?
Specifically, the recommendations that you should not be using absolute epsilons and should not be using floating point whatsoever until you've thoroughly read and understood What Every Computer Scientist Should Know About Floating-Point Arithmetic.
As for this specific piece of code in your question, where it seems your goal is to print a textual representation of the number, simply testing < 0 is correct. And it does not matter whether you write 0 or 0.0.
I have an algorithm which uses floats or doubles to perform some calculations.
Example:
double a;
double b;
double c;
...
double result = c / (b - a);
if ((result > 0) && (result < small_number))
{
// result is relevant...
} else {
// result not required...
}
Now, I am worried about (b - a) might be zero. If it is close to zero but not zero, it does not matter because the result will be out of range to be useful, and I already detect that (as (b - a) approaches zero, result will approach +/- inf, which is not in the range 0-small_number...)
But if the result of (b - a) is exactly zero, I expect that something platform dependant will happen due to divide by zero. I could change the if statement to:
if ((!((b-a) == 0.0)) && ((result = c/(b-a)) > 0) && (result < small_number)) {
but I don't know if (b-a) == 0.0 will always detect equality with zero. I have seen there are multiple representations for exact zero in floating point? How can you test for them all without doing some epsilon check, which I don't need (a small epsilon will be ignored in my algorithm)?
What is the platform independant way to check?
EDIT:
Not sure if it was clear enough to people. Basically I want to know how to find if an expression like:
double result = numerator / denominator;
will result in a floating point exception, a cpu exception, a signal from the operating system or something else.... without actually performing the operating and seeing if it will "throw"... because detecting a "throw" of this nature seems to be complicated and platform specific.
Is ( (denominator==0.0) || (denominator==-0.0) ) ? "Will 'throw'" : "Won't 'throw'"; enough?
It depends on how b and a got their values. Zero has an exact representation in floating point format, but the bigger problem would be almost-but-not-quite zero values. It would always be safe to check:
if (abs(b-a) > 0.00000001 && ...
Where 0.00000001 is whatever value makes sense.
Here's how you do it: instead of checking for (result < small_number), you check for
(abs(c) < abs(b - a) * small_number)
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 did put some kind of zero into float-type variable. As many already said if you want to check result of calculation you may get values very close to zero due to nature of representation.
In brief, we can know a floating number is ZERO exactly if we know it represent format.
In practice, we compare x with a small number. And if x is less than this number, we think x is as same as ZERO functionally (but most of time our small number is still large than zero). This method is very easy, efficient and can cross platform.
Actually, the float and double have been presented by special format, and the widely used one is IEEE 754 in current hardware which divided the number into sign, exponent and mantissa (significand) bits.
So, if we want to check if a float number is ZERO exactly, we can check if both exponent and mantissa is ZERO, see here.
In IEEE 754 binary floating point numbers, zero values are represented
by the biased exponent and significand both being zero. Negative zero
has the sign bit set to one.
Take float for example, we can write a simple code to extract exponent and mantissa bit and then check it.
#include <stdio.h>
typedef union {
float f;
struct {
unsigned int mantissa : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
} parts;
} float_cast;
int isZero(float num) {
int flag = 0;
float_cast data;
data.f = num;
// Check both exponent and mantissa parts
if(data.parts.exponent == 0u && data.parts.mantissa == 0u) {
flag = 1;
} else {
flag = 0;
}
return(flag);
}
int main() {
float num1 = 0.f, num2 = -0.f, num3 = 1.2f;
printf("\n is zero of %f -> %d", num1, isZero(num1));
printf("\n is zero of %f -> %d", num2, isZero(num2));
printf("\n is zero of %f -> %d", num3, isZero(num3));
return(0);
}
Test results:
# is zero of 0.000000 -> 1
# is zero of -0.000000 -> 1
# is zero of 1.200000 -> 0
More examples:
Let's check when the float becomes real ZERO with code.
void test() {
int i =0;
float e = 1.f, small = 1.f;
for(i = 0; i < 40; i++) {
e *= 10.f;
small = 1.f/e;
printf("\nis %e zero? : %d", small, isZero(small));
}
return;
}
is 1.0000e-01 zero? : NO
is 1.0000e-02 zero? : NO
is 1.0000e-03 zero? : NO
is 1.0000e-04 zero? : NO
is 1.0000e-05 zero? : NO
is 1.0000e-06 zero? : NO
is 1.0000e-07 zero? : NO
is 1.0000e-08 zero? : NO
is 1.0000e-09 zero? : NO
is 1.0000e-10 zero? : NO
is 1.0000e-11 zero? : NO
is 1.0000e-12 zero? : NO
is 1.0000e-13 zero? : NO
is 1.0000e-14 zero? : NO
is 1.0000e-15 zero? : NO
is 1.0000e-16 zero? : NO
is 1.0000e-17 zero? : NO
is 1.0000e-18 zero? : NO
is 1.0000e-19 zero? : NO
is 1.0000e-20 zero? : NO
is 1.0000e-21 zero? : NO
is 1.0000e-22 zero? : NO
is 1.0000e-23 zero? : NO
is 1.0000e-24 zero? : NO
is 1.0000e-25 zero? : NO
is 1.0000e-26 zero? : NO
is 1.0000e-27 zero? : NO
is 1.0000e-28 zero? : NO
is 1.0000e-29 zero? : NO
is 1.0000e-30 zero? : NO
is 1.0000e-31 zero? : NO
is 1.0000e-32 zero? : NO
is 1.0000e-33 zero? : NO
is 1.0000e-34 zero? : NO
is 1.0000e-35 zero? : NO
is 1.0000e-36 zero? : NO
is 1.0000e-37 zero? : NO
is 1.0000e-38 zero? : NO
is 0.0000e+00 zero? : YES <-- 1e-39
is 0.0000e+00 zero? : YES <-- 1e-40
UPDATE (2016-01-04)
I've received some downvotes on this answer, and I wondered if I should just delete it. It seems the consensus (https://meta.stackexchange.com/questions/146403/should-i-delete-my-answers) is that deleting answers should only be done in extreme cases.
So, my answer is wrong. But I guess I'm leaving it up because it provides for an interesting "think out of the box" kind of thought experiment.
===============
Bingo,
You say you want to know if b-a == 0.
Another way of looking at this is to determine whether a == b. If a equals b, then b-a will be equal 0.
Another interesting idea I found:
http://www.cygnus-software.com/papers/comparingfloats/Comparing%20floating%20point%20numbers.htm
Essentially, you take the floating point variables you have and tell the compiler to reinterpret them (bit for bit) as signed integers, as in the following:
if (*(int*)&b == *(int*)&a)
Then you are comparing integers, and not floating points. Maybe that will help? Maybe not. Good luck!
I believe that (b-a)==0 will be true exactly in those cases when the c/(b-a) would fail because of (b-a) being zero. The float maths is tricky but questioning this is exaggerating in my opinion. Also I believe that the (b-a)==0 is going to be equivalent to b!=a.
Distinguishing positive and negative 0 is also not necessary. See e.g. here Does float have a negative zero? (-0f)
For epsilon, in there is a standard template definition std::numeric_limits::epsilon(). I guess checking the difference to be bigger than std::numeric_limits::epsilon() should be safe enough to protect against division by zero. No platform dependency here I guess.
You could try
if ((b-a)!=(a-b) && ((result = c/(b-a)) > 0) && (result < small_number))) {
...
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Most effective way for float and double comparison
I have two values(floats) I am attempting to add together and average. The issue I have is that occasionally these values would add up to zero, thus not requiring them to be averaged.
The situation I am in specifically contains the values "-1" and "1", yet when added together I am given the value "-1.19209e-007" which is clearly not 0. Any information on this?
I'm sorry but this doesn't make sense to me.
Two floating point values, if they are exactly the same but with opposite sign, subtracted will produce always 0. This is how floating point operations works.
float a = 0.2f;
float b = -0.2f;
float f = (a - b) / 2;
printf("%f %d\n", f, f != 0); // will print out 0.0000 0
Will be always 0 also if the compiler doesn't optimize the code.
There is not any kind of rounding error to take in account if a and b have the same value but opposite sign! That is, if the higher bit of a is 0 and the higher bit of b is 1 and all other bits are the same, the result cannot be other than 0.
But if a and b are slightly different, of course, the result can be non-zero.
One possible solution to avoid this can be using a tolerance...
float f = (a + b) / 2;
if (abs(f) < 0.000001f)
f = 0;
We are using a simple tolerance to see if our value is near to zero.
A nice example code to show this is...
int main(int argc)
{
for (int i = -10000000; i <= 10000000 * argc; ++i)
{
if (i != 0)
{
float a = 3.14159265f / i;
float b = -a + (argc - 1);
float f = (a + b) / 2;
if (f != 0)
printf("%f %d\n", a, f);
}
}
printf("completed\n");
return 0;
}
I'm using "argc" here as a trick to force the compiler to not optimize out our code.
At least right off, this sounds like typical floating point imprecision.
The usual way to deal with it is to round your numbers to the correct number of significant digits. In this case, your average would be -1.19209e-08 (i.e., 0.00000001192). To (say) six or seven significant digits, that is zero.
Takes the sum of all your numbers, divide by your count. Round off your answer to something reasonable before you do prints, reports comparisons, or whatever you're doing.
again, do some searching on this but here is the basic explanation ...
the computer approximates floating point numbers by base 2 instead of base 10. this means that , for example, 0.2 (when converted to binary) is actually 0.001100110011 ... on forever. since the computer cannot add these on forever, it must approximate it.
because of these approximations, we lose "precision" of calculations. hence "single" and "double" precision floating point numbers. this is why you never test for a float to be actually 0. instead, you test whether is below some threshhold which you want to use as zero.
I wish to round a floating point number to set precision and return the result from a function. For example, I currently have the following function:
inline bool R3Point::
operator==(const R3Point& point) const
{
// Return whether point is equal
return ((v[0] == point.v[0]) && (v[1] == point.v[1]) && (v[2] == point.v[2]));
}
What I wish to do is instead of doing a direct v[i] == point.v[i] comparison, I wish to compare only digits to a certain set precision, so that if v[i] = 0.33349999999999996 and point.v[i] = 0.33350000000000002, my equal comparison will result in TRUE.
I am aware that there's a c++ smanip setprecision ( int n ); function and I've seen it used a lot when displaying output on screen using cout. However, I'm not sure if this can be used within the function like I described.
Thanks.
Generally, == should not be used to compare doubles, you should do something like :
if(v[0] - point.v[0] < 1e-9) { }
You can use abs or fabs if you are not sure of the sign and change the precision 1e-9 accordingly.
Comparing 2 floating point numbers (say a and b), is best done using the following: abs(a-b) < precision. Where abs(x) is the absolute value function, and precision is some small positive number. Often you want to set the precision as a function of the absolute value of the numbers being compared themselves.
I was wondering if there is a way of overcoming an accuracy problem that seems to be the result of my machine's internal representation of floating-point numbers:
For the sake of clarity the problem is summarized as:
// str is "4.600"; atof( str ) is 4.5999999999999996
double mw = atof( str )
// The variables used in the columns calculation below are:
//
// mw = 4.5999999999999996
// p = 0.2
// g = 0.2
// h = 1 (integer)
int columns = (int) ( ( mw - ( h * 11 * p ) ) / ( ( h * 11 * p ) + g ) ) + 1;
Prior to casting to an integer type the result of the columns calculation is 1.9999999999999996; so near yet so far from the desired result of 2.0.
Any suggestions most welcome.
When you use floating point arithmetic strict equality is almost meaningless. You usually want to compare with a range of acceptable values.
Note that some values can not be represented exactly as floating point vlues.
See What Every Computer Scientist Should Know About Floating-Point Arithmetic and Comparing floating point numbers.
There's no accurracy problem.
The result you got (1.9999999999999996) differed from the mathematical result (2) by a margin of 1E-16. That's quite accurate, considering your input "4.600".
You do have a rounding problem, of course. The default rounding in C++ is truncation; you want something similar to Kip's solution. Details depend on your exact domain, do you expect round(-x)== - round(x) ?
If you haven't read it, the title of this paper is really correct. Please consider reading it, to learn more about the fundamentals of floating-point arithmetic on modern computers, some pitfalls, and explanations as to why they behave the way they do.
A very simple and effective way to round a floating point number to an integer:
int rounded = (int)(f + 0.5);
Note: this only works if f is always positive. (thanks j random hacker)
If accuracy is really important then you should consider using double precision floating point numbers rather than just floating point. Though from your question it does appear that you already are. However, you still have a problem with checking for specific values. You need code along the lines of (assuming you're checking your value against zero):
if (abs(value) < epsilon)
{
// Do Stuff
}
where "epsilon" is some small, but non zero value.
On computers, floating point numbers are never exact. They are always just a close approximation. (1e-16 is close.)
Sometimes there are hidden bits you don't see. Sometimes basic rules of algebra no longer apply: a*b != b*a. Sometimes comparing a register to memory shows up these subtle differences. Or using a math coprocessor vs a runtime floating point library. (I've been doing this waayyy tooo long.)
C99 defines: (Look in math.h)
double round(double x);
float roundf(float x);
long double roundl(long double x);
.
Or you can roll your own:
template<class TYPE> inline int ROUND(const TYPE & x)
{ return int( (x > 0) ? (x + 0.5) : (x - 0.5) ); }
For floating point equivalence, try:
template<class TYPE> inline TYPE ABS(const TYPE & t)
{ return t>=0 ? t : - t; }
template<class TYPE> inline bool FLOAT_EQUIVALENT(
const TYPE & x, const TYPE & y, const TYPE & epsilon )
{ return ABS(x-y) < epsilon; }
Use decimals: decNumber++
You can read this paper to find what you are looking for.
You can get the absolute value of the result as seen here:
x = 0.2;
y = 0.3;
equal = (Math.abs(x - y) < 0.000001)