赋给`float`时,何时附加'f'会改变浮动常量的值? [英] When does appending an 'f' change the value of a floating constant when assigned to a `float`?

查看:44
本文介绍了赋给`float`时,何时附加'f'会改变浮动常量的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 floats. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆