C是否舍入浮点常数

时间:2014-03-12 00:35:52

标签: c floating-point floating-point-precision

A question about floating-point precision in Go让我想知道C是如何解决问题的。

在C:中使用以下代码:

float a = 0.1;

a将具有最接近的IEEE 754二进制表示形式:

00111101110011001100110011001101 (Decimal:  0.10000000149011612)

或者只是将其裁剪为:

00111101110011001100110011001100 (Decimal:  0.09999999403953552)

或者根据编译器/平台的不同而不同?

2 个答案:

答案 0 :(得分:6)

允许实现(或者甚至多一个):

  

对于十进制浮点常量,以及当FLT_RADIX不是2的幂时,对于十六进制浮点常量,结果是最接近的可表示值,或紧邻最近可表示值的较大或较小可表示值,在实现定义的方式。

(C11,§6.4.4.2/ 3)

从C99开始,我们已经有了十六进制浮点常量,因此您可以精确指定所需的位(假设实现提供二进制浮点:)),所以您可以说,例如:

float a = 0x1.99999Ap-4;

对于IEEE 754 32位浮点数:

#include <stdio.h>
int main() {
  float a = 0.1;
  float low  = 0x0.1999999p0;
  float best = 0x0.199999ap0;
  float high = 0x0.199999bp0;
  printf("a is %.6a or %.16f, which is either %.16f, %.16f or %.16f\n",
          a, a, low, best, high);
  return 0;
}

答案 1 :(得分:0)

未通过标准规定,但在某些本地硬件上进行测试:

#include <stdio.h>

int
main( int argc, char **argv )
{
float   a = 0.1;
double  b = a;

printf("%.16f\n", b );
}

0.1000000014901161