c - 将 double 转换为 int 的安全方法是什么?

标签 c error-handling casting safety-critical

我得到了一个 legacy code ,其中有人不小心将 double 值分配给 int 变量,例如:

int a = 10;
double b = 20;
a = b;

现在摆脱

warning C4244: '=': conversion from 'double' to 'int', possible loss of data

警告,我尝试编辑上游代码并删除不必要的 double 变量,但结果太乱了!

我也可以使用转换:

a = (int) b;

但实际上并不能保证b 会在整数范围内。我想做一个辅助函数:

int safeD2I(double inputVar){
  if ((inputVar < INT_MAX) && (INT_MIN < inputVar)){
    return (int) inputVar;
  } else {
    exit(-1);
  }
}

但我不确定这是否是最佳实现方式。我想知道是否有更规范的方法来处理这个问题?

我想要的:

  • b 变量超出整数范围的情况下,程序立即停止
  • 向终端打印一条错误消息,指出发生此问题的具体线路和时间。

在此先感谢您的支持。

最佳答案

首先,代码本身没有任何错误或不安全的地方。赋值转换是 C 语言中完全合法的部分。如果这是您不知道是否安全完成的遗留代码,您需要进行分析以确定这一点。

如果您发现确实需要捕获可能的越界值(当转换为 int 时会产生未定义的行为 (!!)),那么您的代码既错误又脆弱.比较如下:

double x;
...
if (x < INT_MAX) ...

胁迫 INT_MAX输入 double为了比较。在实践中double是 IEEE double 和 int是 32 位的,这恰好是安全的,但是如果您更改了 double 就会不安全至 float , 因为 32 位 INT_MAX不能用单精度表示 float .该值将被四舍五入,然后在四舍五入后进行比较。

现在,事实证明您还有一个差一错误(<= INT_MAX,而不是< INT_MAX,是在边界内)以及不正确的逻辑(|| 而不是 &&)所以四舍五入实际上会修复其中的一部分。但依赖它是不对的。相反,您需要制造可以比较的 2 的幂,因此转换为 float 是安全的。例如:

  • if (x < 2.0*(INT_MAX/2+1) && x >= INT_MIN)
  • if (-x > (-INT_MAX-1) && x >= INT_MIN)
  • if (-x > INT_MIN && x >= INT_MIN)

这些都假设INT_MIN实际上是二的幂(全范围二进制补码),这是一个合理的现实世界假设,也是 C2x+ 所要求的。如果你想要更多的通用性,那就需要更多的工作。

最后,我首先写这个作为对你问题的评论,但我想得越多,它确实属于一个答案:根据你的 C 熟练程度,我会非常谨慎 对此代码进行任何不必要的或“清理”更改。你破坏的可能远远多于你修复的。仅在您已完成分析以确定存在事件错误的地方进行更改,并且不要重构事物或更改类型来修复。进行简单的直接内联修复。

关于c - 将 double 转换为 int 的安全方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60801020/

相关文章:

mysql - 错误 1690 (22003) : BIGINT UNSIGNED value is out of range in

c - 无法使用 GNU GCC 在 matlab (Windows) 中编译 C 文件 (MEX)

perl - 如何从Moose构造函数报告错误?

node.js - Node 中的自定义错误代码应使用什么范围?

c++ - 为什么接受用户输入后我的程序由于访问冲突而崩溃?

C# 泛型强制转换

c++ - "bytes to encode the instructions"是什么意思?

c - 程序在执行时终止

c - 使用安全函数将字符串添加到 C 中的字符串

C# dll 中的 C# 转换异常