C#取余与Pow运算结果异常,进制编码还原失败
问题分析与解决方案
问题根源
你遇到的问题核心是浮点数运算的精度限制。代码还原阶段使用Math.Pow(b, i)计算基数的幂,而Math.Pow返回的double类型仅具备53位有效精度——当计算的幂值超过253(约9×1015)时,无法精确表示所有64位无符号整数(ulong是64位)。
以你的测试场景为例:当b=63、i=7时,63^7的准确值是3938980996807,但Math.Pow(63,7)返回的double值会因精度不足被向上取整为3938980996808,比实际值大1。由于该位的digits[i]为1,最终累加得到的r就会比原number大1。
修复方案
替换浮点数幂运算为整数循环累乘,全程用ulong类型计算,彻底避免精度丢失。修改还原部分的代码如下:
ulong r = 0; ulong pow = 1; // 初始为b^0=1 for (int i = 0; i < digits.Count; i++) { r += (ulong)digits[i] * pow; pow *= b; // 每次循环累乘基数,得到b^(i+1) }
这种方式通过整数运算保证幂值的精确性,还原后的r将与原number完全一致。
额外验证
你可以单独测试浮点数运算的误差:
Console.WriteLine(Math.Pow(63,7)); // 输出3938980996808(存在误差) Console.WriteLine(63ul * 63 * 63 * 63 * 63 * 63 * 63); // 输出3938980996807(准确值)
内容的提问来源于stack exchange,提问作者glboothby
相关产品推荐
相关产品推荐

