带指数的浮点文字的类型

Ron*_*Ron 10 c floating-point

具有指数部分的浮点文字的类型是什么,例如123456e-3在 C(99+) 中?它是类型float还是double?当用作float初始化器时float f = 123456e-3; ,它需要有f后缀吗?

dbu*_*ush 9

默认情况下,所有带或不带指数部分的浮点文字都具有 type double。您可以添加f后缀来制作类型floatL制作类型long double

在的情况下float f = 123456e-3;,你初始化float一个double常量,所以精度损失的可能性,但是这种特殊的常量只有具有精度是6位小数所以应该没问题。

  • 这里,“float f = 123456e-3;”和“float f = 123456e-3f;”都会导致存储“0x1.edd2f2p+6”。然而,最佳实践是使用“float”文字常量初始化“float”变量,以避免双重舍入的潜在问题。 (2认同)

Rak*_*lam 7

对于浮点字面量,如果没有定义后缀,它会自动被认为是double.

您可以按照此图表获取后缀:

(no suffix) - double

f/F - float

l/L - long double
Run Code Online (Sandbox Code Playgroud)

所以,对于浮动,它需要有f后缀。


chu*_*ica 7

浮点文字的类型是什么?

浮动常量

C 将这些定义为浮动常量,而不是文字。默认类型为double.
一个fF后缀使得它float
一个lL后缀使得它long double

[编辑] FLT_EVAL_METHOD

C具有FLT_EVAL_METHOD其允许常量解释为更广泛的类型。

例子 FLT_EVAL_METHOD == 2

根据long double类型的范围和精度评估所有操作和常量。

在这种情况下,我希望v1v2具有相同的值 when FLT_EVAL_METHOD == 2,但不同的值 when FLT_EVAL_METHOD == 0

long double v1 = 0.1;
long double v2 = 0.1L;
Run Code Online (Sandbox Code Playgroud)

当用作 float f = 123456e-3 中的 float 初始值设定项时;它需要有后缀吗?

为了最好地将文本转换为float,是的,请使用f.

float f = 123456e-3导致双舍入。2 舍入发生: text->doubledoubleto float

使用 select 值,g可能会使用float g = x.xxxvs获得不同的值g = x.xxxf;。见下文。

双舍入示例

请注意f2f4除了f后缀外,和具有相同的常量。编译器警告f4

警告:从 'double' 到 'float' 的转换会将值从 '9.9999997019767761e-1' 更改为 '1.0e+0f' [-Wfloat-conversion]

#include <stdlib.h>
int main(void) {
  // float has 24 bit significand, double has 53
  float f1 = 0x0.FFFFFFp0f;         // code with 24 bit significand, exact as a float
  printf("%-20a %.17e\n", f1, f1);
  float f2 = 0x0.FFFFFF7FFFFFFCp0f; // code with 54 bit significand, rounds down to nearest float
  printf("%-20a %.17e\n", f2, f2);
  float f3 = 0x0.FFFFFF80000000p0f; // code with 25 bit significand, rounds up to nearest float
  printf("%-20a %.17e\n", f3, f3);
  puts("");
  double d1 = 0x0.FFFFFF7FFFFFF8p0; // code constant with 53 bit significand, exact as a double
  printf("%-20a %.17e\n", d1, d1);
  double d2 = 0x0.FFFFFF7FFFFFFCp0; // code constant with 54 bit significand, rounds up to nearest double
  printf("%-20a %.17e\n", d2, d2);
  float f4 = 0x0.FFFFFF7FFFFFFCp0;  // code constant with 54 bit significand, rounds up to nearest double
                                    // then rounds up again when double converted to float
  printf("%-20a %.17e\n", f4, f4);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出

0x1.fffffep-1        9.99999940395355225e-01
0x1.fffffep-1        9.99999940395355225e-01  f2
0x1p+0               1.00000000000000000e+00

0x1.fffffefffffffp-1 9.99999970197677501e-01
0x1.ffffffp-1        9.99999970197677612e-01
0x1p+0               1.00000000000000000e+00  f4 Double Rounding!
Run Code Online (Sandbox Code Playgroud)

为了最好地将文本转换为long double,一定要使用Lelse 常量只是double精度较低的a 。

long double ld1 = 0x1.00000000000001p1;
printf("%.20Le\n", ld1, ld1);
long double ld2 = 0x1.00000000000001p1L; // "Same" constant as above with an 'L'
printf("%.20Le\n", ld2, ld2);
Run Code Online (Sandbox Code Playgroud)

输出

2.00000000000000000000e+00
2.00000000000000002776e+00
Run Code Online (Sandbox Code Playgroud)