You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x64与arm64架构下Double.NaN运算差异原因咨询

问题:ARM64与X64架构下NaN转int的结果差异原因

我司某服务中的代码在Mac Studio(arm64架构)上运行单元测试时失败,经排查是Double.NaN进行算术运算时的处理方式存在架构差异。我将该问题复现到以下单元测试中,通过添加架构特定断言使其在x64和arm64上均能通过,想请教该现象的原因:

[TestCase]
public void TestNaN()
{
    double nanDouble = double.NaN;
    
    int testInt = (int)(2 * nanDouble);

    if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
    {
        Assert.AreEqual(0, testInt);
    }
    
    if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
    {
        Assert.AreEqual(-2147483648, testInt);
    }
}
原因分析

这本质是不同CPU架构的浮点转整数指令行为差异导致的,核心逻辑如下:

  • 首先明确:2 * double.NaN的结果还是NaN——任何和NaN的算术运算结果都是NaN,这一步在所有架构上完全一致。
  • X64架构(Intel/AMD)的处理:X64使用cvttsd2si指令完成双精度浮点到32位整数的截断转换,当输入是NaN这类无效值时,指令会返回int类型的最小值-2147483648,这是x86/x64架构浮点指令的标准定义。
  • ARM64架构的处理:ARM64对应的转换指令是fcvtzs,该指令定义为:遇到NaN等无法转换的无效浮点值时,直接返回0。
  • .NET的底层映射:.NET在执行(int)doubleValue强制转换时,直接调用了对应架构的原生硬件指令,没有额外做跨架构的统一化处理,所以会直接暴露两种架构的指令行为差异。

简单总结:两种CPU架构对“NaN转整数”这个无效操作的返回值定义不同,而.NET直接复用了硬件指令的行为,最终导致结果差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:19:53