Apple硅arm64与x86_64下double转int64_t的行为差异咨询
问题原因分析
前置背景
int64_t的取值范围是[-9223372036854775808, 9223372036854775807]double类型仅包含53位有效数字,无法精确存储所有64位整数,超过2^53的整数会触发舍入- 测试代码中赋值给
double d的std::numeric_limits<int64_t>::max()即9223372036854775807,超出了double的精确表示范围,会被舍入到最接近的可表示double值2^63(即9223372036854775808),该值已经超出了int64_t的可表示上限。
核心原因
根据C++标准定义,浮点数转换为整数类型时,如果浮点数取值超出目标整数类型的可表示范围,转换行为属于未定义行为,没有统一的执行约束,最终输出完全由硬件架构、编译器版本的实现逻辑决定。
两个平台的行为差异
- x86_64 + gcc7:gcc7直接调用x86指令集的
cvttsd2si硬件指令完成转换,该指令原生设计就是当输入值超出int64_t上限时,返回固定值0x8000000000000000,对应输出-9223372036854775808。 - arm64 + gcc10:arm64架构对应的浮点数转整数指令
fcvtzs默认采用饱和截断规则,当输入值超出int64_t上限时,自动截断到int64_t的最大值9223372036854775807,gcc10直接复用了该硬件行为,因此输出正的最大值。
内容的提问来源于stack exchange,提问作者ledzep2
相关产品推荐
相关产品推荐

