繁体   English   中英

C中的舍入浮点

[英]Rounding floats in C

在测试浮点类型并使用格式说明符%f对其进行打印时,我正在测试其舍入方法。

我已将变量声明为float,并为其指定了值5.123456。 如您所知,浮点数必须至少代表6个有效数字。

然后,我将其值更改为5.1234567并用%f打印该值。 这让我感到困惑,为什么它输出为5.123456。 但是,如果我将变量值更改为5.1234568,它将输出为5.123457。 正确舍入。

如果我不清楚,或者解释很混乱:

float a = 5.1234567
printf("%d", a); 
// prints out as 5.123456

float a = 5.1234568
printf("%d", a); 
// prints out as 5.123457

我已经使用CodeBlocks和MinGW进行了编译,结果相同。

OP正在经历双舍入的影响

首先,编译器将值5.123456、5.11234567等舍入到最接近的可表示float 然后printf()float四舍五入到最接近的0.000001十进制文本表示形式。


我已将变量声明为float,并为其指定了值5.123456。 如您所知,浮点数必须至少代表6个有效数字。

float可以表示大约2 ^ 32个不同的值。 5.123456不是其中之一。 典型float可以代表的最接近值是5.12345600128173828125,它对于6个有效数字是正确的:5.12345 ...

float x = 5.123456f;
//  5.123455524444580078125 representable float just smaller than 5.123456
//  5.123456                OP's code
//  5.12345600128173828125  representable float just larger  than 5.123456 (best)

// The following prints 7 significant digits
// %f prints 6 places after the decimal point.
printf("%f", 5.123456f); // --> 5.123456

对于5.1234567,最接近的float的精确值为5.123456478118896484375。 当使用"%f" ,预期此打印将四舍五入到最接近的0.0000015.123456

float x = 5.1234567f;
//  5.123456478118896484375 representable float just smaller than 5.1234567 (best)
//  5.1234567                OP's code
//  5.1234569549560546875   representable float just larger  than 5.1234567

// %f prints 6 places after the decimal point.
printf("%f", 5.1234567f); // --> 5.123456

有效数字不是小数点后的位数。 它是从最左(最高有效)位开始的位数。

要将float打印为6位有效数字,请使用"%.*e"
有关更多详细信息,请参见Printf宽度说明符以保持浮点值的精度

float x = 5.1234567;         
printf("%.*e\n", 6 - 1, x);  // 5.12346e+00
                             // x xxxxx   6 significant digits

您要在此处显示的数字5.1234567没有确切的浮点表示形式。

如果您在此处查看: https : //www.h-schmidt.net/FloatConverter/IEEE754.html

您会看到此数字已转换为5.1234565或双精度的5.1234564781188965,并将其四舍五入,

数字5.1234568用浮点数表示,并且具有5.123456954956055的双精度表示,因此将其取整。

舍入分为两个级别:

  1. 您的常数5.1234567会四舍五入为最接近的值,该值可以用浮点数(5.123456478 ...)表示。
  2. 浮点数在打印时四舍五入到6位数字。

如果您打印更多位数的值,这将变得显而易见。

得出的结论是,浮点数的尾数有23位,这与6个十进制数字(或实际上是任意数字)不同。 甚至一些看似简单的值(例如0.1)也没有精确的浮点表示形式。

暂无
暂无

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

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