Why am i getting -0 instead of 0? - c

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;

Related

In C why does the power function return 1 when the power is set to 1/2?

When I use the following code I tried to replicate the idea that sqrt(x) of something equals X^(1/2)
pow(x, (1/2);
It returned 1 no matter what value I entered. I already solved this issue with the sqrt function but wanted to know why this is happening for the future.
In it's original form, 1/2 is integer division, producing a result of 0.
Math 101: Anything raised 0, is 1.
1 (integer literal) divided by 2 (integer literal) asks for integer division (on the operator /) which results in 0. From that on, you are giving 0 to a function, pow(3), that converts your 0 into 0.0 (as a double required by the function) and this is what you are calculating, x to the power of 0.0 which is 1.0.
Had you used
pow(x, (1.0/2.0)); /* there's a closing parenthesis missing in your sample code */
using floating point literals, instead of integer, the division should have been floating point, you got 0.5 as result and you should be calculating the square root of x.
By the way, you have a function sqrt(3) to do square roots, in the same library:
pru.c
#include <math.h>
#include <stdio.h>
/* ... */
int main()
{
double x = 625.0;
printf("square root of %.10f is %.10f\n", x, sqrt(x));
printf("%.10f to the power 1/2 is %.10f\n", x, pow(x, 1.0/2.0));
return 0;
}
Executing that code gives:
$ make pru
cc -O2 -Wno-error -Werror -o pru pru.c
$ pru
square root of 625.0000000000 is 25.0000000000
625.0000000000 to the power 1/2 is 25.0000000000
$ _
Integer division yields an integer result, so 1/2 yields 0, not 0.5. At least one of the operands needs to be a floating point value to get a floating point result, such as 1 / 2.0. Although you can just write 0.5 and save the heartburn.
1/2 in c++ is 0 since both are integers. You can use 1.0/2.0 or 0.5 to do what you want.

Checking if a double is equal to -0.00

I am making this big program in C, which is a part of my homework. 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?
You can use the standard macro signbit(arg) from math.h. It will return nonzero value if arg is negative and ​0​ otherwise.
From the man page:
signbit() is a generic macro which can work on all real floating-
point types. It returns a nonzero value if the value of x has its
sign bit set.
This is not the same as x < 0.0, because IEEE 754 floating point
allows zero to be signed. The comparison -0.0 < 0.0 is false, but
signbit(-0.0) will return a nonzero value.
NaNs and infinities have a sign bit.
Also, from cppreference.com:
This macro detects the sign bit of zeroes, infinities, and NaNs. Along
with copysign, this macro is one of the only two portable ways to
examine the sign of a NaN.
Very few calculations actually give you a signed negative zero. What you're probably observing is a negative value close to zero that has been truncated by your formatting choice when outputting the value.
Note that -0.0 is defined to be equal to 0.0, so a simple comparison to 0.0 is enough to verify a signed zero.
If you want to convert an exact signed zero -0.0 to 0.0 then add 0.0 to it.
Most likely, your program has a small negative value, not zero, which printf formats as “-0.00”. To print such numbers as “0.00”, you can test how printf will format them and replace the undesired string with the desired string:
#include <stdio.h>
#include <string.h>
void PrintAdjusted(double x)
{
char buffer[6];
int result = snprintf(buffer, sizeof buffer, "%.2f", x);
/* If snprintf produces a result other than "-0.00", including
a result that does not fit in the buffer, use it.
Otherwise, print "0.00".
*/
if (sizeof buffer <= result || strcmp(buffer, "-0.00") != 0)
printf("%.2f", x);
else
printf("0.00");
}
This is portable. Alternatives such as comparing the number to -0.005 have portability issues, due to implementation-dependent details in floating-point formats and rounding methods in printf.
If you truly do want to test whether a number x is −0, you can use:
#include <math.h>
…
signbit(x) && x == 0
There are two functions you need here.
First, the signbit function can tell you if the sign bit is set on a floating point number. Second, the fpclassify function will tell you if a floating point number is some form of 0.
For example:
double x = 0.0;
double y = -0.0;
double a = 3;
double b = -2;
printf("x=%f, y=%f\n", x, y);
printf("x is zero: %d\n", (fpclassify(x) == FP_ZERO));
printf("y is zero: %d\n", (fpclassify(y) == FP_ZERO));
printf("a is zero: %d\n", (fpclassify(a) == FP_ZERO));
printf("b is zero: %d\n", (fpclassify(b) == FP_ZERO));
printf("x sign: %d\n", signbit(x));
printf("y sign: %d\n", signbit(y));
printf("a sign: %d\n", signbit(a));
printf("b sign: %d\n", signbit(b));
Output:
x=0.000000, y=-0.000000
x is zero: 1
y is zero: 1
a is zero: 0
b is zero: 0
x sign: 0
y sign: 1
a sign: 0
b sign: 1
So to check if a value is negative zero, do the following:
if (fpclassify(x) == FP_ZERO)) {
if (signbit(x)) {
printf("x is negative zero\n");
} else {
printf("x is positive zero\n");
}
}
To always get the non-negative version, you don't need the comparison at all.
You can take the absolute value all of the time. If the value is non-negative, fabs should return the original value.

Looping over a range of floats in C

I am trying to write a program in C to accomplish the following task.
Input: Three double-precision numbers, a, b, and c.
Output: All the numbers from b to a, that can be reached by decrements of c.
Here is a simple program (filename: range.c).
#include <stdlib.h>
#include <stdio.h>
int main()
{
double high, low, step, var;
printf("Enter the <lower limit> <upperlimit> <step>\n>>");
scanf("%lf %lf %lf", &low, &high, &step);
printf("Number in the requested range\n");
for (var = high; var >= low; var -= step)
printf("%g\n", var);
return 0;
}
However, the for loop behaves rather bizarrely for some inputs. For instance, the following.
10-236-49-81:stackoverflow pavithran$ ./range.o
Enter the <lower limit> <upperlimit> <step>
>>0.1 0.9 0.2
Number in the requested range
0.9
0.7
0.5
0.3
10-236-49-81:stackoverflow pavithran$
I cannot figure out why the loop quits at var = 0.1. While for another input, it behaves as expected.
10-236-49-81:stackoverflow pavithran$ ./range.o
Enter the <lower limit> <upperlimit> <step>
>>0.1 0.5 0.1
Number in the requested range
0.5
0.4
0.3
0.2
0.1
10-236-49-81:stackoverflow pavithran$
Had the weird behaviour in the first situation got something to do with numeric precision?
How can I ensure that the range will always contain floor((high - low)/step) + 1 numbers?
I have tried an alternate method of looping over floats, where I scale the loop variables to integers, and print the result of the loop variable divided by the scaling used. But there's perhaps a better way...
Using a double as a counter in a for loop requires very careful consideration. In many instances it's best avoided.
I'm sure you know that not all numbers that are exact in decimal are also exact in binary floating point. In fact, for IEEE754 floating point, only dyadic rationals are. So 0.5 is, but 0.4, 0.3, 0.2, and 0.1 are not.
The closest IEEE754 floating point double to 0.2 is actually the slightly larger 0.200000000000000011102230246251565404236316680908203125.
In your case a repeated subtraction of this from 0.9 eventually causes a number whose first significant figure is a to become a number whose first significant figure is a - 3: your bug then manifests itself.
The simple remedy is to work in integers, decement by 1 each time, and scale your output using step.

asin() function in C returns NaN when more iterations used

I have a homework in C. We have to write our own asin() function with Taylor method, and we can't use math.h
It works fine, but once I put higher count of iterations(int i), it returns NaN(Not a Number), and when I use low count of i, the number is not exact. Can anyone help me with this?
double my_asin(double x)
{
int i = 0;
double vypocet = x;
double y = vypocet;
for(i=1;i<=10000;i++)
{
vypocet*=((x*x)*(2*i-1)*(2*i-1))/((2*i)*(2*i+1));
y+=vypocet;
}
printf("my_asin = %.10e\n", y);
return y;
}
EDIT: Thank you all! finished it :)
Two things are required for your answer :
Regarding maths : The series expansion you are coding is a sin inverse (arcsin) and expecting an output in radian.
sin^(-1)x=x+1/6x^3+3/(40)x^5+5/(112)x^7+(35)/(1152)x^9+... . As you can see this is an expansion which is monotonically increasing and expecting value (input) between [-1,1] only. When you plug in large values e.g. 10 you are bound to get results you don't expect.So , plug in correct values. I guess, put correct values [-1,1] when calling the function my_asin() and your code would work fine FOR THE number of ITERATIONS YOU HAVE NOW.
e.g 1.5146343691e+000 looks fine for 90 degrees or pi/2 or my_asin(1).
2 .Regarding Floating Point (double i.e. single prrecision floating point ):They cant represent all the numbers on the real line, their range is a subset of R.And when there is a number that can't be represented correctly by their 32 bits encoding (IEEE 754) you will get error in result.
Number as simple as 0.1 cant be represented exactly using floating point.
Check these pages for FP Errors and FP Exceptions :
http://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html
http://www.gnu.org/software/libc/manual/html_node/FP-Exceptions.html#FP-Exceptions

How to convert negative zero to positive zero in C?

Hello I'm learning Objective C and I was doing the classic Calculator example.
Problem is that I'm getting a negative zero when I multiply zero by any negative number, and I put the result into a (double) type!
To see what was going on, I played with the debugger and this is what I got:
(gdb) print -2*0
$1 = 0
(gdb) print (double) -2 * 0
$2 = -0
In the second case when I cast it to a double type, it turns into negative zero! How can I fix that in my application? I need to work with doubles.
How can I fix the result so I get a zero when the result should be zero?
I did a simple test:
double d = (double) -2.0 * 0;
if (d < 0)
printf("d is less than zero\n");
if (d == 0)
printf("d is equal to zero\n");
if (d > 0)
printf("d is greater than zero\n");
printf("d is: %lf\n", d);
It outputs:
d is equal to zero
d is: -0.000000
So, to fix this, you can add a simple if-check to your application:
if (d == 0) d = 0;
There is a misunderstanding here about operator precedence:
(double) -2 * 0
is parsed as
((double)(-(2))) * 0
which is essentially the same as (-2.0) * 0.0.
The C Standard informative Annex J lists as Unspecifier behavior Whether certain operators can generate negative zeros and whether a negative zero becomes a normal zero when stored in an object (6.2.6.2).
Conversely, (double)(-2 * 0) should generate a positive zero 0.0 on most current platforms as the multiplication is performed using integer arithmetic. The C Standard does have support for architectures that distinguish positive and negative zero integers, but these are vanishingly rare nowadays.
If you want to force zeros to be positive, this simple fix should work:
if (d == 0) {
d = 0;
}
You could make the intent clearer with this:
if (d == -0.0) {
d = +0.0;
}
But the test will succeed also if d is a positive zero.
Chux has a simpler solution for IEC 60559 complying environments:
d = d + 0.0; // turn -0.0 to +0.0
http://en.wikipedia.org/wiki/Signed_zero
The number 0 is usually encoded as +0, but can be represented by either +0 or −0
It shouldn't impact on calculations or UI output.
How can I fix that in my application?
Code really is not broken, so nothing needs to be "fixed". #kennytm
How can I fix the result so I get a zero when the result should be zero?
To easily get rid of the - when the result is -0.0, add 0.0. Code following standard (IEC 60559 floating-point) rules will produce drop the - sign.
double nzero = -0.0;
printf("%f\n", nzero);
printf("%f\n", nzero + 0.0);
printf("%f\n", fabs(nzero)); // This has a side effect of changing all negative values
// pedantic code using <math.h>
if (signbit(nzero)) nzero = 0.0; // This has a side effect of changing all negative values
printf("%f\n", nzero);
Usual output.
-0.000000
0.000000
0.000000
0.000000
Yet for general double x that may have any value, hard to beat the following. #Richard J. Ross III #chqrlie The x + 0.0 approach has an advantage in that likely does not introduce a branch, yet the following is clear.
if (x == 0.0) x = 0.0;
Note: fmax(-0.0, 0.0) may produce -0.0.
In my code (on C MPI intel compiler) -0.0 and +0.0 are not the same.
As an example:
d = -0.0
if (d < 0.0)
do something...
and it is doing this "something".
also adding -0.0 + 0.0 = -0.0...
GCC was seemingly optimizing out the simple fix of negzero += 0.0 as noted above until I realized that -fno-signed-zeros was in place. Duh.
But in the process I did find that this will fix a signed zero, even when -fno-signed-zeros is set:
if (negzero > -DBL_MIN && negzero < DBL_MIN && signbit(negzero))
negzero = 0.0;
or as a macro:
#define NO_NEG_ZERO(a) ( (a) > -DBL_MIN && (a) < DBL_MIN && signbit(a) ? 0.0 : (a) )
negzero = NO_NEG_ZERO(negzero)
Note that the comparitor is < and > (not <= or >=) so a really is zero! (OR it is a subnormal number...but nevermind the guy behind the curtain.)
Maybe this answer is slightly less correct in the sense that a value of between DBL_MIN and -DBL_MIN will be converted to 0.0, in which case this isn't the way if you need to support subnormal numbers.
If you do need subnormal numbers (!) then perhaps your the kind of person who plays with -fno-signed-zeros, too.
The lesson here for me and subnormal-numbers-guy is this: if you play outside of spec then expect out-of-spec results ;)
(Sorry, that was not PC. It could be subnormal-numbers-person...but I digress.)

Resources