-1
#include <stdio.h>

int main() { 
float k;
    scanf("%f", &k);
    printf("%f", k);
} 

In this simple program when I enter a number containing at most 8 digits then it is displayed correctly.

But if I exceed 8 digits i.e. for the input 123456789 the output is 123456792.

Why this is happening? Well the fun fact is that if I enter any number between 123456789 and 123456796 then it always shows 123456792.

Is it something related to the 8 decimal precision of floating numbers?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • 1
    https://stackoverflow.com/questions/12560291/set-back-default-precision-c – Hariom Singh Aug 16 '17 at 13:49
  • 4
    @HariomSingh How is that linked question related? It's not even in the same language. – Toby Aug 16 '17 at 13:50
  • @Toby question was originally double-tagged with [tag:c++], removed it because neither the code nor the text refers to C++. –  Aug 16 '17 at 13:53
  • 1
    read [Precision limits on integer values](https://en.wikipedia.org/wiki/Single-precision_floating-point_format#Precision_limits_on_integer_values) –  Aug 16 '17 at 13:55
  • ...and maybe you need `double` instead of `float`. – Jabberwocky Aug 16 '17 at 13:57
  • And this can also be of interest: [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Jabberwocky Aug 16 '17 at 13:58
  • Chaitanya Vaishampayan: Curious what was your expectation of what values `float` would have trouble? did you expect all possible numeric inputs to print out the same? – chux - Reinstate Monica Aug 16 '17 at 14:33
  • see https://en.wikipedia.org/wiki/IEEE_754 – pynexj Aug 16 '17 at 14:53

1 Answers1

5

Floating point types have a limited precision. For a float on your machine, which appears to be 32 bit, it has 24 bits of precision (23 explictly stored, 1 implied). That means integers greater than ~16000000, which require more than 24 bits to store, can't be represented exactly with this datatype.

For example, the value 123456789 you used has a binary representation of:

111 0101 1011 1100 1101 0001 0101

This value takes up 27 bits which is more than is available. So it is rounded to the closest value that can be stored with 23 bits, which is 123456792. In binary:

111 0101 1011 1100 1101 0001 1000

For this value, the lower 3 bits with value 0 are not explicitly stored.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Off by 1: The ~16000000 is about right, but typical `float` has 24 bits of precision. 23 are directly encoded and 1 implied. This first inexact conversion of an integer to `float` is with 16,777,217 (0x1000001), a 25-bit integer. – chux - Reinstate Monica Aug 16 '17 at 14:27
  • 1
    @chux Good catch. Updated to reflect. – dbush Aug 16 '17 at 14:29