Andrei Cristian Andrei Cristian - 10 months ago 37
C Question

C casting double ->long -> short (using right shift ">>")

I have a small code which does some number transformations. I want to turn a number from double to long and then using right bit shift to cast it to short. But it gives me different results and I don't know why.

I have 3 numbers in an array and I make the sum of them using a

loop and every time I am gonna cast the result to

There is a number with
more exactly
. Adding this to the total and then subtracting it gives me different results.

I can't figure out why does this occur and how can I manage this particular case.

Here is my code:

#include <stdio.h>

#define DOUBLETOLONG(number) (long)(number)
#define NEAREST(number) ((short)((number + 32768) >> 16))

int main() {
int k = 0;
double array[3] ={ 41451520.000000, 63897600.000000007, -63897600.000000007 };
double total_x = array[0];
short j = LONGTOSHORT(total_x);

printf("j = %d\n", j);

for (k = 1; k < 3; k++) {
total_x = total_x+array[k];
j = LONGTOSHORT(total_x);
printf("j = %d\n", j);
return 0;

This are the results:

j = 633
j = 1608
j = 632

Answer Source

41451520 + 63897600 = 105349120

In a double this integer can still be accurately represented. However, we didn't account for the fractional part 0.000000007. Let's check what the next biggest double is:

#include <stdio.h>
#include <math.h>

int main(int argc, char** argv) {
    printf("%.23f\n", nextafter(105349120.0, INFINITY));
    return 0;

Turns out, it's 105349120.000000014901.... Let's put those next to eachother:


This means that 105349120.000000007 is closer to 105349120 than the next bigger double, so it correctly gets rounded down to 105349120.

However, when we subtract again, 105349120 - 63897600.000000007 gets rounded down, because the next smaller double than 41451520 is (nextafter(41451520.0, 0)) 41451519.999999992549.... Put them next to eachother:


Yep, closer to the first double below 41451520 than 41451520 itself. So it correctly gets rounded down to 41451519.999999992549....

When you convert 41451519.999999992549... to an integer it floors the number, resulting in one less than what you expect.

Floating point math is full of surprises. You should read What Every Computer Scientist Should Know About Floating-Point Arithmetic, but perhaps it's still too advanced for now. But it's important to be aware that yes, floating point is full of surprises, but no it isn't magic, and you can learn the pitfalls.