0

These numbers add up to zero, but the code puts out 18 as the result. For my task its required that the numbers are defined as floats.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {


float b1 = 23.0;   
float b2 = 42.0;
float b3 = 2073741824.0;
float b4 = -2073741714.0;
float b5 = -64.0;
float b6 = -111.0;
float be;

be = b1+b2+b3+b4+b5+b6;

printf("Das Float Ergebnis ist:   %f\n", be);

return (EXIT_SUCCESS);
}

2 Answers2

3

-2073741714.0 is not typically exactly representable as a float. Use wider types or accept imprecision. float as a 32-bit variable can not exactly encode every number, just about 232 of them. The typical closest one is -2073741696

float b4 = -2073741714.0;
printf("b4 = %f\n", b4);
// typical output
// b4 = -2073741696.000000

Instead consider either wider FP types.

int main(void) {
  double b1 = 23.0;
  double b2 = 42.0;
  double b3 = 2073741824.0;
  double b4 = -2073741714.0;
  double b5 = -64.0;
  double b6 = -111.0;
  double be;
  printf("b4 = %f\n", b4);

  be = b1 + b2 + (b3 + b4) + b5 + b6;
  printf("Das Float Ergebnis ist:   %f\n", be); // Das Float Ergebnis ist:   0.000000
  return (EXIT_SUCCESS);
}

Or use wider math

int main(void) {
  float b1 = 23.0;
  float b2 = 42.0;
  float b3 = 2073741824.0;
  double b4 = -2073741714.0;
  float b5 = -64.0;
  float b6 = -111.0;
  float be;
  printf("b4 = %f\n", b4);

  be = b1 + b2 + (b3 + b4) + b5 + b6;
  printf("Das Float Ergebnis ist:   %f\n", be); // Das Float Ergebnis ist:   0.000000
  return (EXIT_SUCCESS);
}

A 3rd choice is to re-arrange the evaluation order. This will help, yet not overcome limitations of float.

int main(void) {
  float b1 = 23.0;
  float b2 = 42.0;
  float b3 = 2073741824.0;
  float b4 = -2073741714.0;
  float b5 = -64.0;
  float b6 = -111.0;
  float be;

  be = b1 + b2 + (b3 + b4) + b5 + b6;
  printf("Das Float Ergebnis ist:   %f\n", be);  // Das Float Ergebnis ist:   18.000000
  return (EXIT_SUCCESS);
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

Some will argue that the exact width of a float is unspecified by the C standard and therefore implementation-dependent, but on any platform you are likely to encounter a C float means an IEEE754 single-precision number.

It's a lot of math over there if you are interested, but, in a nutshell, a float can store about 7-8 significant decimal digits. Let me illustrate this with an example:

2073741824.0; // float
       ^^^ ^ // all this information is most likely lost

By most likely I mean that you should NEVER assume that the program will remeber those digits.

2073741xxx.x; // float
       ^^^ ^ // this is how you should treat you number form a safe programmer's prespective
Valdrinium
  • 1,398
  • 1
  • 13
  • 28
  • 2
    Thank you for the excelent explanation. This was not mentioned in any tutorial i read. – DerEntinator Oct 07 '17 at 21:17
  • 1
    "float can store about 7-8 significant decimal digits" is an OK approximation. [binary](https://en.wikipedia.org/wiki/IEEE_754) has, at worst, 6 significant decimal digits (research `FLT_DIG`). 6-9 would be a better generalization. – chux - Reinstate Monica Dec 11 '17 at 15:10