Matlab 64位算术运算结果与手动计算值不符的原因咨询
问题1:sin(i*pi/2)计算结果与理论循环序列不符的原因
- 你的猜测是正确的,这一差异确实和
pi不是精确的机器浮点数直接相关。 - Matlab中内置的
pi是IEEE 754双精度浮点数所能表示的最接近数学意义上π的近似值,本身存在极小的舍入误差,并非精确值。因此计算i*(pi/2)时,当i不为0,得到的并不是精确的kπ/2(k为整数),带入sin函数计算后自然会得到和理论值存在1e-16量级微小偏差的结果,比如本该为0的位置会出现极小的非零值,本该为±1的位置会出现和±1极接近的数值。 - 如果需要得到和理论值完全一致的结果,可以通过
mod(i,4)做分支判断输出对应值,或者对a的结果做极小阈值的舍入处理即可。
问题2:大整数相加后减回原数结果与预期20000不符的原因
- 这是IEEE 754双精度浮点数的有效位数限制导致的。
- 双精度浮点数的尾数仅有52位,加上隐含的前导1,总共能无误差表示的整数范围为
-2^53 ~ 2^53,超出这个范围的整数只能表示为对应区间最小精度单位(ulp,即相邻两个可表示浮点数的差值)的整数倍,无法覆盖所有整数。 - 你用到的
2^60已经远大于2^53,其对应的ulp为2^(60-52)=256,也就是说2^60附近的浮点数最小间隔为256,只有256的整数倍的增量才能被精确记录。而20000不是256的整数倍,相加时会被自动舍入到最接近的256整数倍数值,导致c = a + b的结果和理论上的a+20000存在偏差,最终d = c - a的结果自然不等于20000。 - 如果需要做这类大整数的精确运算,可以改用Matlab的符号运算工具,或者提前将变量声明为
uint64/int64整数类型:a = uint64(2)^60; b = uint64(20000); c = a + b; d = c - a % 此时输出为精确的20000
内容的提问来源于stack exchange,提问作者user9532692
相关产品推荐
相关产品推荐

