简体   繁体   English

C:舍入浮点数

[英]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?为什么数字 125向下舍入为 1.2 而 135向上舍入为 1.4? For example, it also happens with the numbers 105, 115, 125, 155, 165.例如,它也会发生在数字 105、115、125、155、165 上。

The C standard does not fully specify either the float format or how rounding is performed. C 标准没有完全指定float格式或如何执行舍入。 Most C implementations today use the IEEE-754 binary32 format for float .今天大多数 C 实现都使用 IEEE-754 binary32 格式来表示float In this format:在这种格式中:

  • The representable value nearest 1.24 is 1.2400000095367431640625.最接近 1.24 的可表示值为 1.2400000095367431640625。
  • The representable value nearest 1.25 is 1.25.最接近 1.25 的可表示值为 1.25。
  • The representable value nearest 1.26 is 1.2599999904632568359375.最接近 1.26 的可表示值为 1.2599999904632568359375。
  • The representable value nearest 1.34 is 1.34000003337860107421875.最接近 1.34 的可表示值为 1.34000003337860107421875。
  • The representable value nearest 1.35 is 1.35000002384185791015625.最接近 1.35 的可表示值为 1.35000002384185791015625。
  • The representable value nearest 1.36 is 1.36000001430511474609375.最接近 1.36 的可表示值为 1.36000001430511474609375。

If you change %0.1f in the printf calls to %.99g , your C implementation will likely show you those values.如果您将printf调用中的%0.1f更改为%.99g .99g ,您的 C 实现可能会向您显示这些值。

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.这是几乎总是用于算术运算(尤其是加法、减法、乘法和除法)的规则,因此您的 C 实现可能在计算(float)124/100等时使用它。

That rule is also often used when converting numbers from the internal binary float format to numerals in character strings, as with printf .在将数字从内部二进制float格式转换为字符串中的数字时,也经常使用该规则,例如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: (在这种情况下,该规则的使用频率较低,因为某些转换软件未编写为使用根据此规则始终产生正确结果所需的精度或计算。)您观察到的 output 与此规则的使用一致:

  • Rounding 1.2400000095367431640625 to one digit after the decimal point produces “1.2”, since it is closer to 1.2 than to 1.3.将 1.2400000095367431640625 四舍五入到小数点后一位得到“1.2”,因为它更接近 1.2 而不是 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.将 1.25 四舍五入到小数点后的一位数字会产生“1.2”,因为 1.2 和 1.3 是并列的,而 1.2 具有偶数位。
  • Rounding 1.2599999904632568359375 to one digit after the decimal point produces “1.3” since it is closer to 1.3 than to 1.2.将 1.2599999904632568359375 四舍五入到小数点后一位数得到“1.3”,因为它更接近 1.3 而不是 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.将 1.34000003337860107421875 四舍五入到小数点后一位得到“1.3”,因为它更接近 1.3 而不是 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.将 1.35000002384185791015625 四舍五入到小数点后一位得到“1.4”,因为它更接近 1.4 而不是 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.将 1.36000001430511474609375 四舍五入到小数点后一位数得到“1.4”,因为它更接近 1.4 而不是 1.3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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