在下面的代码中,
#include <stdio.h> float area(float var) { return (var*var); } int main() { float side; printf("nEnter the side of square : "); scanf("%f",&side); **printf("The area is : %.1f",area(side));** return 0; }
如果格式说明符为"%,则输入为15.5。1f";则输出为:
240.3
并且当,
输入为15.5,带有格式说明符"%。2f";则输出为:
240.25(这实际上是正确的值)
为什么当格式说明符为"%.1f"时,值会四舍五入,而不是只打印到小数点后第一位,输出为240.2
规范要求四舍五入。在f
格式说明符中,C17规范表示
表示浮点数的双参数转换为[-]ddd.ddd样式的十进制表示法,其中小数点字符后的位数等于精度规范。如果精度缺失,则取6;如果精度为零并且没有指定#标志,则不会显示小数点字符。如果出现小数点字符,则在其前面至少会出现一位数字。该值将四舍五入到适当的位数。
注意最后一句话。
现在,有很多取整的方法。我认为CCD_ 2是为了纪念";定向舍入模式";由fesetround
设置,在我的系统中也不例外。
#include <fenv.h>
#include <stdio.h>
// gcc doesn't recognize or need this.
#pragma STDC FENV_ACCESS ON
int main( void ) {
fesetround( FE_DOWNWARD );
printf( "%.1fn", 0.66 ); // 0.6
fesetround( FE_TONEAREST );
printf( "%.1fn", 0.66 ); // 0.7
}
编译器浏览器演示
我的系统默认为四舍五入到最近值。当它需要选择两个数字中哪一个最接近时(例如0.5),它四舍五入到最接近的偶数。
#include <stdio.h>
int main( void ) {
printf( "%.0fn", 0.5 ); // 0
printf( "%.0fn", 1.5 ); // 2
printf( "%.0fn", 2.5 ); // 2
printf( "%.0fn", 3.5 ); // 4
printf( "%.0fn", 4.5 ); // 4
}
编译器浏览器演示
(我使用了.0f
和.5
,因为5/10可以用浮点数精确表示。)
我不知道规范是否要求默认四舍五入,但当人们想减少数字中的小数位数时,这是很自然的做法。
如果它不这样做,也会产生很多奇怪的结果。您希望printf( "%.1fn", 0.3 );
打印0.2
吗?好吧,如果你们四舍五入而不是四舍五进到最接近的,就会这样。
很多数字都是二进制周期性的,包括1/10、2/10、3/10、4/10、6/10、7/10、8/10和9/10。这些不能用浮点数精确地表示。理想情况下,编译器使用最接近的可表示数字,这个数字有时高一点,有时低一点。
#include <stdio.h>
int main( void ) {
printf( "%.100gn", 0.1 ); // 0.1000000000000000055511151231257827021181583404541015625
printf( "%.100gn", 0.3 ); // 0.299999999999999988897769753748434595763683319091796875
}
编译器浏览器演示
如果要截断printf
,则printf( "%.1fn", 0.3 );
将打印0.2
。
#include <fenv.h>
#include <stdio.h>
// gcc doesn't recognize or need this.
#pragma STDC FENV_ACCESS ON
int main( void ) {
fesetround( FE_DOWNWARD );
printf( "%.1fn", 0.3 ); // 0.2
fesetround( FE_TONEAREST );
printf( "%.1fn", 0.3 ); // 0.3
}
编译器浏览器演示
最后,我在规范中没有找到任何关于如何四舍五入到最近值的内容。四舍五入到偶数的决定似乎是编译器的决定。
这种打破平局的规则没有积极/消极的偏见,也没有偏向零或偏离零的偏见,这是一种自然的选择。甚至是";IEEE 754操作中用于二进制浮点格式结果的默认舍入模式">