Java中计算以2为底的对数精度异常,致2的幂判断程序出错
解决2的幂判断中的浮点数精度问题
原代码依赖对数计算判断结果是否为整数,但float类型的精度限制会导致大数计算时出现近似误差(比如2^30对应的对数计算结果因浮点近似变成29.999998),完全可以用整数位运算替代浮点运算,既彻底避免精度问题,又大幅提升执行效率。
最优解决方案:位运算判断
2的正整数次幂的二进制表示有且仅有一个1,例如:
- 2^0 = 1 →
0b1 - 2^1 = 2 →
0b10 - 2^30 = 1073741824 →
0b1000000000000000000000000000000
对这类数执行n & (n - 1)运算时,会把唯一的1变为0,最终结果为0;而非2的幂的数执行该运算后结果必然不为0。结合2的幂必须是正整数的特性,代码可修改为:
class Solution { // Function to check if given number n is a power of two. public static boolean isPowerofTwo(long n) { // 先排除非正整数的情况 if (n <= 0) { return false; } // 位运算判断:仅当n是2的幂时,n & (n-1)结果为0 return (n & (n - 1)) == 0; } }
其他可选方案(效率略低)
如果一定要保留对数相关的思路,可以改用精度更高的double类型,并引入极小的误差容忍范围,判断计算结果是否接近整数:
public static boolean isPowerofTwo(long n) { if (n <= 0) { return false; } double x = Math.log(n) / Math.log(2); // 允许极小的误差,判断x是否接近整数 return Math.abs(x - Math.round(x)) < 1e-10; }
但这种方法依然依赖浮点计算,效率和可靠性都不如位运算,不推荐使用。
内容的提问来源于stack exchange,提问作者Ananya
相关产品推荐
相关产品推荐

