Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
so i am having this strange problem here and I don't know what to do.
so in the following I am posting an excerpt of my code:
printf("%lf , %lf \n", cGrid_Y,sideLength);
printf("%lf <= %lf\n", Point_Y, cGrid_Y+sideLength);
bool x = (Point_Y <= (sideLength + cGrid_Y) );
printf("%s \n", x ? "true" : "false");
cGrid_Y and sideLength are doubles. And I am getting this output:
-12.800000 , 12.800000
0.000000 <= -0.000000
false
So my question is, why I am not getting a true ?
This is not a problem with negative zeros. 0.0 <= -0.0 is true. The problem is that your values are not actually zero or negative zero but some very small value that's being rounded to 0 for presentation when you ask printf to show it rounded to 6 decimal places. Either print with %e or %g (which will use exponential notation to show a better approximation) or %.1100f which is sufficient precision to show the exact value of any double.
So my question is, why I am not getting a true ?
Are you sure that Point_Y == 0.0? Same for the sum of sideLength + cGrid_Y?
Check your assumptions:
printf("Point_Y is zero: %d\n", Point_Y == 0.0);
printf("`sideLength + cGrid_Y` is zero: %d\n", (sideLength + cGrid_Y) == 0.0);
The reason you got confused is because by default printf's floats/doubles are't printed to full precision.
#include <stdio.h>
int main()
{
double x = 0.0000001;
printf("x: %f\n", x);
}
outputs: x: 0.000000
#edit I wrote a stupid mistaken thing: I thought that negative zero doesn't equal positive zero, whereas after reading it all properly -0 equals +0.
The source of your problem: you are trying to test whether two doubles are equal, and this is a terrible idea, due to the imprecision of floating point representation. Note the common example: 0.1 + 0.2 does NOT equal 0.3:
Is floating point math broken?
https://www.quora.com/Why-is-0-1+0-2-not-equal-to-0-3-in-most-programming-languages
You cannot represent 12.8 in binary without losing a part of the imformation, due to the fundamental nature of how this number is stored in the computer's memory.
The same way you can't represent 1/7 in our "normal" decimal representation of numbers with a finite amount of digits.
Related
I have written a code in c which gives me rotation of point by angle given in the form of triples.
When I compile and run for test case it gives me output as -0,7 .
Where as the same code in python gives me output as 0,7 .
When I run the same code on online compiling platforms it gives me correct output.
I am using codeblocks windows 10 os.
Is there something wrong with codeblocks?
What should i do?
C code:
#include<stdio.h>
#include<math.h>
int main()
{
double xp,yp,xq,yq,a,b,c;
double t,xn,yn;
int z;
scanf("%d",&z);
// printf("Enter coordinates of p \n");
scanf("%lf%lf",&xp,&yp);
// printf("\nEnter triple \n");
scanf("%lf%lf%lf",&a,&b,&c);
// printf("\nEnter coordinates of q \n");
scanf("%lf%lf",&xq,&yq);
t=asin(b/c);
if(z==0)
{
xn=xp*cos(t)-yp*sin(t)-xq*cos(t)+yq*sin(t)+xq;
yn=xp*sin(t)+yp*cos(t)-xq*sin(t)-yq*cos(t)+yq;
}
else
{
xn=xp*cos(t)+yp*sin(t)-xq*cos(t)-yq*sin(t)+xq;
yn=-xp*sin(t)+yp*cos(t)+xq*sin(t)-yq*cos(t)+yq;
}
printf("%lf %lf",xn,yn);
return 0;
}
Output:
0
4 7
3 4 5
2 3
-0.000000 7.000000
Process returned 0 (0x0) execution time : 10.675 s
Press any key to continue.
https://stackoverflow.com/questions/34088742/what-is-the-purpose-of-having-both-positive-and-negative-zero-0-also-written
The most likely thing here is that you don't actually have a signed -0.0, but your formatting is presenting it to you that way.
You'll get a signed negative zero in floating point if one of your calculations yields a negative subnormal number that's rounded to zero.
If you do indeed have a pure signed zero, then one workaround is to clobber it with a the ternary conditional operator as printf does reserve the right to propagate the signed zero into the output: f == 0.0 ? 0.0 : f is one such scheme or even with the flashier but obfuscated f ? f : 0.0. The C standard defines -0.0 to be equal to 0.0. Another way (acknowledge #EricPostpischil) is to add 0.0 to the value.
For floating point values there are two zeroes 0.0 and -0.0. They compare as equal (e.g. -0.0 == 0.0 returns 1) but they are two distinct values. They are there for symmetry, because for any small value other than 0, the sign does make a mathematical difference. For some edge cases they make a difference. For example 1.0/0.0 == INFINITY and 1.0/-0.0 == -INFINITY. (INFINITY, -INFINITY and NAN) are also values that the floating point variables can take.
To make printf not print -0 for -0.0 and any small that would be truncated to 0 or -0, one way is to artificially put very small values to 0.0, for example:
if(abs(x) < 1e-5) x = 0.0;
Given this code that my professor gave us in an exam which means we cannot modify the code nor use function from other libraries (except stdio.h):
float x;
(suppose x NOT having an integer part)
while (CONDITION){
x = x*10
}
I have to find the condition that makes sure that x has no valid number to the right of decimal point not giving attention to the problems of precision of a float number (After the decimal point we have to have only zeros). I tried this condition:
while ((fmod((x*10),10))){
X = X*10
}
printf(" %f ",x);
example:
INPUT x=0.456; --------> OUTPUT: 456.000
INPUT X=0.4567;--------> OUTPUT; 4567.000
It is important to be sure that after the decimal point we don't have any
significant number
But I had to include math.h library BUT my professor doesn't allow us to use it in this specific case (I'm not even allowed to use (long) since we never seen it in class).
So what is the condition that solve the problem properly without this library?
As pointed out here previously:Due to the accuracy of floats this is not really possible but I think your Prof wants to get something like
while (x - (int)x != 0 )
or
while (x - (int)x >= 0.00000001 )
You can get rid of the zeroes by using the g modifier instead of f:
printf(" %g \n",x);
There is fuzziness ("not giving attention to the problems of precision of a float number") in the question, yet I think a sought answer is below, assign x to an integer type until x no longer has a fractional part.
Success of this method depends on INT_MIN <= x <= INT_MAX. This is expected when the number of bits in the significant of float does not exceed the value bits of int. Although this is common, it is not specified by C. As an alternative, code could with a wider integer type like long long with a far less chance of the range restriction issue.
Given the rounding introduced with *10, this method is not a good foundation of float to text conversion.
float Dipok(float x) {
int i;
while ((i=x) != x) {
x = x*10;
}
return x;
}
#include <assert.h>
#include <stdio.h>
#include <float.h>
void Dipok_test(float x) {
// suppose x NOT having an integer part
assert(x > -1.0 && x < 1.0);
float y = Dipok(x);
printf("x:%.*f y:%.f\n", FLT_DECIMAL_DIG, x, y);
}
int main(void) {
Dipok_test(0.456);
Dipok_test(0.4567);
return 0;
}
Output
x:0.456000000 y:456
x:0.456699997 y:4567
As already pointed out by 2501, this is just not possible.
Floats are not accurate. Depending on your platform, the float value for 0.001 is represented as something like 0.0010000001 in fact.
What would you expect the code to calculate: 10000001 or 1?
Any solution will work for some values only.
I try to answer to my exam question please if I say something wrong correct me!
It is not possible to find a proper condition that makes sure that there are no valid number after the decimal point. For example : We want to know the result of 0.4*20 which is 8.000 BUT due to imprecision problems the output will be different:
f=0.4;
for(i=1;i<20;i++)
f=f+0.4;
printf("The number f=0.4*20 is ");
if(f!=8.0) {printf(" not ");}
printf(" %f ",8.0);
printf("The real answer is f=0.4*20= %f",f);
Our OUTPUT will be:
The number f=0.4*20 is not 8.000000
The real answer is f=0.4*20= 8.000001
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 6 years ago.
I tried to sum some numbers in a for loop but it didn't go as I expected
float sum = 0;
int i;
printf("0.1+0.1=%f\n", 0.1 + 0.1);
for (i = 0; i<1000000; i++)
{
sum = sum + 0.1;
}
printf("the sum need to be 100000 \n");
printf("the real sum is:\n %f\n", sum);
system("PAUSE");
this program prints:
0.1+0.1=0.200000
the sum need to be 100000
the real sum is:
100958.343750
Press any key to continue . . .
can you explain please this strange result?
the international standard for floating point numbers does not have an exact representation for some decimal numbers.
http://en.wikipedia.org/wiki/IEEE_754
It is due to the way they are stored in memory, the way the mantissa and exponent are stored.
https://en.wikipedia.org/wiki/Floating_point
This is also the reason why you should never compare two float numbers even if they look "the same".
I still remember how surprised I was the fist time a simple code comparing two float numbers didn't work :) This alone would open a dedicated universe of discussions. It is very worth reading anyway:
http://floating-point-gui.de/errors/comparison/
The floating numbers are stored in memory as x*2^y where x is between 0 and 1 with some precision and y is integer and so they accurately don't represent most numbers, they represent numbers "close enough".
When you do this addition multiple times, the error is just more visible.
You can use double type for better accuracy.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
say i have:
55.3 and want 55
55.6 and want 56
81.1 and want 81
etc.
i have been trying to use the round() function but it seems to keep giving me the highest value for all decimal places.
OP has not posted code that failed. Certain OP coded incorrectly.
Using round() is the correct way to round a double before converting to an int. Of course it must be in range.
#include <math.h>
#include <assert.h>
int round_to_int(double x) {
x = round(x);
assert(x >= INT_MIN);
assert(x < (INT_MAX/2 + 1)*2.0);
return (int) x;
}
See How to test for lossless double / integer conversion? for details about the assert()s.
Why not use (int)(x + 0.5);?
1) It fails for negative numbers.
2) It can fail for the double just smaller than 0.5 as the x + 0.5 can round to 1.0.
3) When the precision of int exceeds double, values where the least significant bit is 0.5 or 1.0, x+0.5 may round to the next integer.
4) Unadorned, it has no range checking.
In the olden days we used to say int the_int = (int)(some_double + 0.5); (obviously beware if you are dealing with negative values too).
Increase the magnitude by one half and truncate:
int round_up_or_down(double x)
{
return x > 0 ? x + 0.5 : x - 0.5;
}
This distributes the real intervals uniformly:
...
[-1.5, -0.5) => -1
[-0.5, +0.5) => 0
[+0.5, +1.5) -> +1
...
This question already has answers here:
Why adding these two double does not give correct answer? [duplicate]
(2 answers)
Closed 8 years ago.
I'm a bit of C newbie but this problem is really confusing me.
I have a variable double = 436553940.0000000000 (it was cast from an Int) and an other variable double 0.095832496.
My result should be 436553940.0958324*96*, however I get 436553940.0958324*67*.
Why does this happen and how can I prevent it from happening?
The number you expect is simply not representable by a double. The value you receive is instead a close approximation based on rounding results:
In [9]: 436553940.095832496
Out[9]: 436553940.09583247
In [18]: 436553940.095832496+2e-8
Out[18]: 436553940.09583247
In [19]: 436553940.095832496+3e-8
Out[19]: 436553940.0958325
In [20]: 436553940.095832496-2e-8
Out[20]: 436553940.09583247
In [21]: 436553940.095832496-3e-8
Out[21]: 436553940.0958324
You've just run out of significand bits.
Doubles are not able to represent every number. We can write some C++ code (that implements doubles in the same way) to show this.
#include <cstdio>
#include <cmath>
int main() {
double x = 436553940;
double y = 0.095832496;
double sum = x + y;
printf("prev: %50.50lf\n", std::nextafter(sum, 0));
printf("sum: %50.50lf\n", sum);
printf("next: %50.50lf\n", std::nextafter(sum, 500000000));
}
This code computes the sum of the two numbers you are talking about, and stores it as sum. We then compute the next representable double before that number, and after that number.
Here's the output:
[11:43am][wlynch#watermelon /tmp] ./foo
prev: 436553940.09583240747451782226562500000000000000000000000000
sum: 436553940.09583246707916259765625000000000000000000000000000
next: 436553940.09583252668380737304687500000000000000000000000000
So, we are not able to have the calculation equal 436553940.0958324_96_, because that number is not a valid double. So the IEEE-754 standard (and your compiler) defines some rules that tell us how the number should be rounded, to reach the nearest representable double.