You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何正确执行64位算术?Agda中64位无符号整数算术处理方法

在Agda中处理64位算术的解决方案

嘿,针对你提出的两个64位算术相关问题,我来分享下在Agda里的实用处理方式:

1. 正确执行64位算术的通用方式

在Agda里做64位算术,最稳妥的路径有两种,按需选择:

  • 优先用标准库/成熟第三方库:Agda的官方标准库(agda-stdlib)已经封装了全套固定宽度数值类型及运算,不用自己从零造轮子:
    • 64位有符号整数:用Data.Int.Int64(部分新版本标准库支持),自带合规的加减乘除等运算,严格遵循有符号64位的溢出规则。
    • 64位浮点数:Data.Float模块的Float类型对应IEEE 754双精度(也就是64位浮点),包含所有基础浮点运算。
    • 64位无符号整数:后面会专门讲,其实标准库也有现成实现。
  • 自定义实现(特殊需求场景):如果需要定制溢出行为、添加额外证明逻辑,可以基于Fin类型手动构建64位数值类型。比如用Fin 2^64表示无符号64位整数,然后自己实现加法、乘法等运算,同时用Agda的证明能力验证运算的正确性。不过这种方式比较繁琐,只推荐给有特殊需求的场景。

2. 64位无符号整数(uint64)算术的处理方法

你说没找到64位无符号整数的运算原语,大概率是没注意到标准库的Data.Word模块——这里面的Word64就是专门为64位无符号整数设计的,而且自带全套原语级运算:

  • 导入并直接使用标准库:在你的Agda文件顶部导入模块,就能直接用现成的运算:
    open import Data.Word using (Word64; _+_; _-_; _*_; _div_; _mod_; _∧_; _∨_; _xor_; shiftL; shiftR)
    
    这些运算都是基于编译器后端的原生64位无符号操作实现的,自动处理无符号溢出(按模2^64规则),效率和正确性都有保障。
  • 定制溢出行为(如果需要):如果不想默认的模运算,而是要检测溢出,可以基于Word64封装逻辑。比如写一个带溢出标志的加法:
    open import Data.Bool using (Bool)
    open import Data.Nat using (ℕ; _+_; _>_)
    open import Data.Word using (Word64; _+_; toℕ; fromℕ)
    
    private
      max-uint64 : ℕ
      max-uint64 = 18446744073709551615 -- 2^64 - 1
    
    addWithOverflow : Word64 → Word64 → (Word64 × Bool)
    addWithOverflow a b = 
      let sum = a + b
          overflow = toℕ a + toℕ b > max-uint64
      in (sum, overflow)
    
    你还可以用Agda的证明能力,进一步验证这个溢出检测逻辑的正确性。
  • 替代方案:基于Fin类型手动定义:如果因为某些原因无法使用标准库的Word64,可以用Fin (2^64)来表示无符号64位整数,然后利用Fin类型自带的模运算特性实现算术操作。不过这种方式需要编写大量的证明代码来保证运算合规,远不如直接用标准库高效。

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

火山引擎 最新活动