赋给`float`时,何时附加'f'会改变浮动常量的值? [英] When does appending an 'f' change the value of a floating constant when assigned to a `float`?
问题描述
将 f
应用于浮点常量似乎在将常量分配给 float
时没有什么区别.
Applying an f
to a floating point constant does not seem to make a difference when assigning the constant to a float
.
int main(void) {
float f;
// 1 2345678901234567
f = 3.1415926535897932;
printf("%.6a %.8f pi 3.1415926535897932\n", f, f);
f = 3.1415926535897932f; // v
printf("%.6a %.8f pi 3.1415926535897932f\n", f, f);
}
带有或不带有 f
的值都相同
With or without the f
, the value is the same
// value value code
0x1.921fb6p+1 3.14159274 pi 3.1415926535897932
0x1.921fb6p+1 3.14159274 pi 3.1415926535897932f
为什么要使用 f
?
推荐答案
这是每个添加 f
很少会有所不同,但在某些情况下会有所不同.当也省略 f
时,功能良好的编译器可能会发出警告.
Appending an f
seldom make a difference, yet does in select cases. A well enabled compiler may emit a warning when the f
is omitted too.
float f = 3.1415926535897932; // May generate a warning
警告:从"double"到"float"的转换将值从"3.1415926535897931e + 0"更改为"3.14159274e + 0f" [-Wfloat-conversion]
warning: conversion from 'double' to 'float' changes value from '3.1415926535897931e+0' to '3.14159274e+0f' [-Wfloat-conversion]
要使值有所不同,请注意可能的双舍入问题.
To make a value difference, watch out for potential double rounding issues.
第一次舍入是由于代码的文本被转换为浮点类型.
The first rounding is due to code's text being converted to the floating point type.
结果要么是最接近的可表示值,要么是较大或较小的可表示值以实现定义的方式选择的,与最接近的可表示值紧邻的值.C17dr§6.4.4.2 3
the result is either the nearest representable value, or the larger or smaller representable value immediately adjacent to the nearest representable value, chosen in an implementation-defined manner. C17dr § 6.4.4.2 3
一种非常常见的实现定义的方式是将源代码文本转换为最接近的 double
(不带 f
)或后缀为 f
的最接近的 float
.出租人质量的实施有时是第二好的选择.
A very common implementation-defined manner is to convert the source code text to the closest double
(without the f
) or to the closest float
with the f
suffix. Lessor quality implementations sometimes form the 2nd best choice.
将 double
FP常量分配给 float
会导致再次舍入.
Assignment of a double
FP constant to a float
incurs another rounding.
如果要转换的值在可以表示但不能精确表示的值的范围内,则结果是以实现定义的方式选择的最接近的较高值或最接近的较低可表示值.C17dr§6.3.1.4 2
If the value being converted is in the range of values that can be represented but cannot be represented exactly, the result is either the nearest higher or nearest lower representable value, chosen in an implementation-defined manner. C17dr § 6.3.1.4 2
一种非常常见的实现定义的方式是将 double
转换为最接近的 float
-平整度.(编译时间舍入可能受各种编译器设置的影响.)
A very common implementation-defined manner is to convert the double
to the closest float
- ties to even. (Compile time rounding may be affected by various compiler settings.)
双舍入值更改
请考虑以下情况:源代码使用值非常接近到两个 float
值之间的一半.
Consider the case when source code uses a value very close to half-way between 2 float
values.
如果没有 f
,则将代码四舍五入为 double
可能会导致该值恰好介于2个 float
之间.然后,将 double
转换为 float
可能不同于带有 f
的".
Without an f
, the rounding of code to a double
may result in a value exactly half-way between 2 float
s. The conversion of the double
to float
then could differ from "with an f
".
使用 f
,转换将导致最接近的 float
.
With an f
, the conversion results in the closest float
.
#include <math.h>
#include <stdio.h>
int main(void) {
float f;
f = 10000000.0f;
printf("%.6a %.3f 10 million\n", f, f);
f = nextafterf(f, f + f);
printf("%.6a %.3f 10 million - next float\n", f, f);
puts("");
f = 10000000.5000000001;
printf("%.6a %.3f 10000000.5000000001\n", f, f);
f = 10000000.5000000001f;
printf("%.6a %.3f 10000000.5000000001f\n", f, f);
puts("");
f = 10000001.4999999999;
printf("%.6a %.3f 10000001.4999999999\n", f, f);
f = 10000001.4999999999f;
printf("%.6a %.3f 10000001.4999999999f\n", f, f);
}
输出
0x1.312d00p+23 10000000.000 10 million
0x1.312d02p+23 10000001.000 10 million - next float
// value value source code
0x1.312d00p+23 10000000.000 10000000.5000000001
0x1.312d02p+23 10000001.000 10000000.5000000001f // Different, and better
0x1.312d04p+23 10000002.000 10000001.4999999999
0x1.312d02p+23 10000001.000 10000001.4999999999f // Different, and better
舍入模式
在向上,向下或朝零取整模式时,不太可能出现有关双取整的问题.在中途情况下,第二次舍入使方向正确时,就会出现这种情况.
The issue about double rounding is less likely when the rounding mode is up, down or towards zero. It arises when the 2nd rounding compounds the direction on half-way cases.
发生率
问题-相对来说很少见.即使代码常量采用十进制或十六进制形式,也存在问题.具有随机常数:约2 30 中的1.
Issue occurs when code converts inexactly to a double
that is very near half-way between 2 float
values - so relatively rare. Issue applies even if the code constant was in decimal or hexadecimal form. With random constants: about 1 in 230.
推荐
很少有一个主要的问题,但是一个 f
后缀最好获得一个 float
的最佳值并静默警告.
Rarely a major concern, yet an f
suffix is better to get the best value for a float
and quiet a warning.
这篇关于赋给`float`时,何时附加'f'会改变浮动常量的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!