You need to enable JavaScript to run this app. Delphi中如何检测运算结果是否超出数值类型的最大值限制?
优惠活动
大模型
产品
解决方案
定价
更多

Delphi中如何检测运算结果是否超出数值类型的最大值限制?

整数运算溢出识别的实现方法

上述代码的判断逻辑完全失效的核心原因:Delphi 默认对整数运算采用静默回绕的溢出处理机制。32位有符号Integer的最大值为2147483647($7FFFFFFF),两个最大值相加时,二进制加法结果为$FFFFFFFE,对应有符号整数的回绕值为-2。这个回绕过程在赋值完成时就已经发生,后续拿已经回绕的结果和MaxInt做大小比较,永远不可能得到成立的判断结果。

可落地的溢出识别方案

  • 方案1:启用编译器内置溢出检测
    可以在项目全局配置中打开「溢出检查」开关,也可以通过局部编译指令精准控制检测范围:在需要检测的代码段前加{$OVERFLOWCHECKS ON},代码段结束后再用{$OVERFLOWCHECKS OFF}恢复默认设置。开启后只要整数运算出现目标类型可取值范围外的结果,程序会直接抛出EIntOverflow运行时异常,不需要手动编写边界判断逻辑,直接在异常捕获分支处理溢出场景即可。这种方式的检测覆盖全场景,不存在逻辑漏洞。

  • 方案2:运算前前置边界预判
    不开启异常检测的场景下,不能在运算完成后用回绕值做判断,必须在执行加法前根据数值大小预判溢出风险。对于有符号整数a、b,二者相加超出类型最大值的充要条件是:a和b均为正数,且a > 类型最大值 - b;二者相加低于类型最小值的充要条件是:a和b均为负数,且a < 类型最小值 - b。
    对应代码的修正逻辑如下:

    procedure TForm1.FormClick(Sender: TObject);
    var
      _Integer1, _Integer2: Integer;
    begin
      _Integer1 := MaxInt;
      // 运算前预判是否会正溢出
      if (_Integer1 > 0) and (_Integer1 > MaxInt - _Integer1) then
      begin
        Caption := '运算结果超出Integer取值范围';
      end
      else
      begin
        _Integer2 := _Integer1 + _Integer1;
        Caption := IntToStr(_Integer2);
      end;
    end;
    

    这种纯数值判断的方式性能开销极低,适合对运行效率要求高的场景。

  • 方案3:用更大范围的类型承接中间运算
    选择取值范围远大于原目标类型的数值类型承接运算结果,从根源上避免运算过程中的静默回绕。比如处理32位Integer的运算时,用64位的Int64类型存储中间结果,两个MaxInt相加的结果远小于Int64的取值上限,运算过程不会发生回绕,后续直接拿这个未回绕的结果和原类型的最大值做比较即可:

    procedure TForm1.FormClick(Sender: TObject);
    var
      _Integer1, _Integer2: Integer;
      TempResult: Int64;
    begin
      _Integer1 := MaxInt;
      TempResult := Int64(_Integer1) + _Integer1;
      if TempResult > MaxInt then
      begin
        Caption := '运算结果超出Integer取值范围';
      end
      else
      begin
        _Integer2 := Integer(TempResult);
        Caption := IntToStr(_Integer2);
      end;
    end;
    

注意:整数溢出的本质是二进制位的回绕,一旦回绕发生,原数值的大小关系、正负属性都会完全失效,所有基于运算完成后的数值编写的判断逻辑,都无法准确识别溢出场景。

内容的提问来源于stack exchange,提问作者SHIN JaeGuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 10:45:03