Carmack的快速开平方根倒数算法
基本原理
需求
32位浮点表示法:二进制的科学计数法
符号位1+阶码8(有符号的反码表示幂指数)+小数位23(二进制小数首位必为1,默认,只需表示小数位即可)
字符串形式:
正数符号位
故:
对x取对数:
泰勒近似:
而
源代码作者采取
C代码实现
float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
python实现
import struct
import math
def fast_inverse_square_root(number):
threehalfs = 1.5
x2 = number * 0.5
y = number
i = struct.unpack('i', struct.pack('f', y))[0]
i = 0x5f3759df - (i >> 1)
y = struct.unpack('f', struct.pack('i', i))[0]
y = y * (threehalfs - (x2 * y * y))
y = y * ( threehalfs - ( x2 * y * y ) ); # 2nd iteration, this can be removed
return y
# 测试
number = 101.0
inverse_sqrt = fast_inverse_square_root(number)
error = inverse_sqrt / (1/math.sqrt(number))
print("Fast Inverse Square Root of", number, "is:", inverse_sqrt, "error", error)
在这段代码中,struct.unpack('i', struct.pack('f', y))[0]
这行代码涉及到了struct
模块的使用,主要是对浮点数和整数进行打包和解析操作。让我解释一下各个参数的含义:
-
struct.pack('f', y)
:struct.pack(format, value)
函数用于将值打包为指定格式的字节对象。'f'
是格式化字符串,代表将值打包为浮点数。y
是要打包的值,即输入的浮点数。
-
struct.unpack('i', ...)
:struct.unpack(format, data)
函数用于从字节对象中解析出值。'i'
是格式化字符串,代表解析的值为整数。...
是前面打包得到的字节对象,即浮点数y
打包后的字节对象。
-
struct.unpack('i', struct.pack('f', y))[0]
:- 这个表达式的含义是先将浮点数
y
打包为字节对象,然后再从字节对象中解析出整数值。 [0]
表示取解析结果中的第一个值,因为struct.unpack
返回的是一个元组。
- 这个表达式的含义是先将浮点数
综合起来,这行代码的作用是将浮点数y
转换为字节对象(即二进制表示),然后再从字节对象中解析出整数值。这个操作是算法中的一个关键步骤,用于对输入的浮点数进行位操作和处理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具