1
#include <stdio.h>

int main(){

    float a;

    scanf("%f",&a);
    a=(int)(a*1000+0.5);
    printf("%.5f\n",a);
    a=a/1000;
    printf("%.5f\n",a);

    return 0;
}

This program is written to round off a floating point number up to 3 decimal points in a specific way; e.g. 65.43296 should print as 65.43200, not 65.432.

According to logic it should work but I am getting an unexpected answer like following:

1234.56789        
1234568.00000    
1234.567993

Explain this behaviour.

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • 2
    `float` doesn't have very much precision. – user253751 Aug 16 '18 at 01:48
  • 1
    you could change a from float to double, and then change your format specifiers from `%f` to `%lf`, but you still might have rounding errors for some values due to the way floating point numbers are represented. – bruceg Aug 16 '18 at 01:56
  • 1
    You might want to have a look at this related question: [How many significant digits have floats and doubles in java](https://stackoverflow.com/questions/13542944/how-many-significant-digits-have-floats-and-doubles-in-java). The question discusses Java, but the same logic applies to C. – lurker Aug 16 '18 at 02:15
  • See [What Every Computer Scientist Should Know About Floating-Point Arithmetic](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html); and [Originalpdf](http://www.itu.dk/~sestoft/bachelor/IEEE754_article.pdf) – David C. Rankin Aug 16 '18 at 02:56
  • Also related: [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Gerhardh Aug 16 '18 at 06:34

2 Answers2

1

Although input was "1234.56789", that is only near the value saved in float a.

float as 32-bit object, can only store exactly about 232 different values. Due to the typical binary encoding of a float, 1234.56789 is not one of those 232. Instead the nearest float is used.

1234.56787109375   // nearest float's exact value
1234.56789
1234.5679931640625 // next nearest float's exact value

a*1000+0.5 can be expected to result in 1234568.375 and (int)(a*1000+0.5) to 1234568.0. So far no great surprise.

The quotient a/1000; is also a float and since it too is not one of those 232, the result is the nearest float

1234.5679931640625 // nearest float.
1234.568           // math result of 1234568.0/1000
1234.568115234375  // next nearest float

printf("%.5f\n", 1234.5679931640625) is then as seen by OP.

1234.56799

In general, float will provide expected answers when the number of leading significant digits if 6 or less. OP's expectation of "1234.56800" is 9 digits.


Had code used double, similar unexpected answers can occur when the number of leading significant digits exceeds 15.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

The explanation for the inconsistency in your problem is the number of decimal places the float type works on. It has a simple precision range of 3.4 E-38 to 3.4E+38 (has 4 bytes). In case you should use the double has range of 1.7 E-308 to 1.7E+308 however takes up more memory (8 bytes).

#include <stdio.h>

int main(){

    double a;

    scanf("%lf",&a);
    a=(int)(a*1000+0.5);
    printf("%.5f\n",a);
    a=a/1000;
    printf("%.5lf\n",a);

    return 0;
}