Dear all

when i do some float arithmetic calculation in the kernel function some results give -0.0 instead of 0.0

what does that mean?

Without a small, self-contained, program that reproduces your observation it is impossible to say. Keep in mind that floating-point operations usually incur rounding errors, so a result that is mathematically zero doesn’t necessarily result in zero when evaluated in finite-precision floating-point arithmetic. The reverse is also true: Floating-point computation may return zero although the result is not zero mathematically.

If you have not had the chance yet, I would suggest reading David Goldberg’s seminal paper “What Every Computer Scientist Should Know About Floating-Point Arithmetic”, available, for example, here:

https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Typical signed integer representations use 2’s-complement representation of positive and negative numbers. The value of 0 has only one representation (one possible bit pattern) and it is by convention positive.

Typical floating point representations use IEEE-754 representations (32-bit and 64-bit). These representations have a separate sign bit to represent the sign of the mantissa. Therefore there are conceivably at least two bit patterns that could represent zero - for example all zero mantissa with the sign bit zero (the usual representation) but also all zero mantissa with the sign bit one - yielding -0.0

In addition to the link provided by njuffa, the wikipedia article will give a basic overview:

thank you all

you means that -0.0 is a correct answer?

Without knowing what your code is calculating, it is impossible to say. To raise just one issue, how are you converting the floating-point data into a human readable string? Depending on the format specifier used in printf(), a small negative value could print as -0.0. Example:

```
#include <stdio.h>
#include <stdlib.h>
__global__ void kernel (void)
{
float a = 0.9999999f;
float r = logf (a);
printf ("result is % .1f\n", r);
printf ("result is % 15.8e\n", r);
}
int main (void)
{
kernel <<<1,1>>>();
cudaDeviceReset();
return EXIT_SUCCESS;
}
```

I had used this

```
printf(" temp[%d][%d] %.7f \n ", ty, tx, temp[ty][tx]);
```

As I said, the printf() format specifier is just one aspect to look at. The “.7f” format specifier may still be hiding information. To avoid not seeing all the information, I would suggest using format “% 15.8e” to print data of type ‘float’ and format “% 23.16e” for data of type ‘double’ to make sure small values don’t display as zero.

As txbob pointed out earlier, zeroes are signed in IEEE-754 floating point arithmetic, and -0.0 can therefore be a valid result (see example below). Whether -0.0 is the result you should expect for your code only a closer look at the actual computation can reveal.

```
#include <stdio.h>
#include <stdlib.h>
__global__ void kernel (void)
{
float a = -1e-20f;
float r = a * a * a;
printf ("result is % .1f\n", r);
printf ("result is % 15.8e\n", r);
}
int main (void)
{
kernel <<<1,1>>>();
cudaDeviceReset();
return EXIT_SUCCESS;
}
```

thank you for your efforts

i used 15.8e format and still appear -0.000000…

As my example in #7 shows, -0.0 can easily occur as the valid result of a floating-point computation. The range of numbers that can be represented by a given floating-point type is limited. If the numbers become too small, they will be turned into zeroes. Depending on whether the true mathematical result would be negative or positive, either -0.0 or +0.0 is produced. In my example program above, the true result would be -1e-60, and since that is too small to be represented in a ‘float’, the result is -0.0.

It occurred to me that depending on your background, Goldberg’s paper that I recommended above may look a bit daunting as an introduction to the intricacies of floating-point arithmetic. If so, you may want to try this alternative resource to get started: http://floating-point-gui.de/

thank you