简体   繁体   中英

C: Rounding floats

Could you please explain this code:

  printf("Value1: %0.1f \n", (float)124/100); // = 1.2
  printf("Value1: %0.1f \n", (float)125/100); // = 1.2
  printf("Value1: %0.1f \n", (float)126/100); // = 1.3
  printf("\n");
  printf("Value2: %0.1f \n", (float)134/100); // = 1.3
  printf("Value2: %0.1f \n", (float)135/100); // = 1.4
  printf("Value2: %0.1f \n", (float)136/100); // = 1.4

Why is the number 125 rounding down to 1.2 and 135 rounding up to 1.4? For example, it also happens with the numbers 105, 115, 125, 155, 165.

The C standard does not fully specify either the float format or how rounding is performed. Most C implementations today use the IEEE-754 binary32 format for float . In this format:

  • The representable value nearest 1.24 is 1.2400000095367431640625.
  • The representable value nearest 1.25 is 1.25.
  • The representable value nearest 1.26 is 1.2599999904632568359375.
  • The representable value nearest 1.34 is 1.34000003337860107421875.
  • The representable value nearest 1.35 is 1.35000002384185791015625.
  • The representable value nearest 1.36 is 1.36000001430511474609375.

If you change %0.1f in the printf calls to %.99g , your C implementation will likely show you those values.

The most common rounding rule used is to round to the nearest representable value and, in case there is a tie, to round to the tied value with an even low digit. This is the rule almost always used in arithmetic operations (notably addition, subtraction, multiplication, and division), so your C implementation likely uses it when calculating (float)124/100 and so on.

That rule is also often used when converting numbers from the internal binary float format to numerals in character strings, as with printf . (The rule is used a little less often in this case because some conversion software is not written to use the precision or calculations necessary to always produce correct results according to this rule.) The output you observe is consistent with use of this rule:

  • Rounding 1.2400000095367431640625 to one digit after the decimal point produces “1.2”, since it is closer to 1.2 than to 1.3.
  • Rounding 1.25 to one digit after the decimal point produces “1.2” since 1.2 and 1.3 are tied and 1.2 has the even low digit.
  • Rounding 1.2599999904632568359375 to one digit after the decimal point produces “1.3” since it is closer to 1.3 than to 1.2.
  • Rounding 1.34000003337860107421875 to one digit after the decimal point produces “1.3” since it is closer to 1.3 than to 1.4.
  • Rounding 1.35000002384185791015625 to one digit after the decimal point produces “1.4” since it is closer to 1.4 than to 1.3.
  • Rounding 1.36000001430511474609375 to one digit after the decimal point produces “1.4” since it is closer to 1.4 than to 1.3.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM