主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

整数到浮点数的转换存在精度损失

在将整数转换为浮点数类型时丢失的最低有效位

描述

当将整数值转换为无法表示原始整数值的浮点类型时,会发生此缺陷。

例如,值 long int 1234567890L 对类型为 float 的变量而言过大。

风险

如果浮点类型无法表示整数值,则其行为是未定义的(请参阅 C11 标准 6.3.1.4,第 2 段)。例如,变量值的最低有效位可能会被丢弃,从而导致意外的结果。

修复

转换为能够表示整数值的浮点类型。

例如,如果 float 数据类型无法表示整数值,则使用 double 数据类型代替。

在编写将整数转换为浮点类型函数时,在转换之前,先检查整数值是否可以在浮点类型中表示。例如,DBL_MANT_DIG * log2(FLT_RADIX) 代表类型 double 中 2 进制数字的位数。在转换为类型 double 之前,请检查该数字是否大于或等于要转换的整数的精度。要确定整数 num 的精度,请使用以下代码:

 size_t precision = 0;
 while (num != 0) {
    if (num % 2 == 1) {
      precision++;
    }
    num >>= 1;
 }

一些实现提供了一个内置函数来确定整数的精度。例如,GCC 提供函数 __builtin_popcount

示例

全部展开

#include <stdio.h>

int main(void) {
  long int big = 1234567890L;
  float approx = big;
  printf("%ld\n", (big - (long int)approx));
  return 0;
}

在此 C 代码中,long int 变量 big 被转换为 float

更正 - 使用更宽的浮点类型

一种可能的更正方法是将数据类型从 float 转换为 double

#include <stdio.h>

int main(void) {
  long int big = 1234567890L;
  double approx = big;
  printf("%ld\n", (big - (long int)approx));
  return 0;
}

结果信息

组:数值
语言:C | C++
默认值:关闭
命令行语法:INT_TO_FLOAT_PRECISION_LOSS
影响

版本历史记录

在 R2018b 中推出