首页 > 编程语言 >Carmack的快速开平方根倒数算法(Fast inverse square root)

Carmack的快速开平方根倒数算法(Fast inverse square root)

时间:2024-06-04 10:11:30浏览次数:20  
标签:inverse frac struct 浮点数 number Carmack root 字节

基本原理

需求\(y =\frac{1} {\sqrt{x} }\)

\(log(a^b×a^c)=bloga+cloga=(b+c)loga\)

32位浮点表示法:二进制的科学计数法
符号位1+阶码8(有符号的反码表示幂指数)+小数位23(二进制小数首位必为1,默认,只需表示小数位即可)

../all images/快速开平方根倒数算法(/i/l/?n=23&i=blog/3329763/202406/3329763-20240604100744947-1851611316.webp)-20240511163945890.webp-20240511163945890.webp)

字符串形式:\(S_0​E_1​E_2​...E_7​E_8​M_9​M_{10}​...M_{30}​M_{31}​\)

正数符号位\(S_0\)忽略,并引入两个常量\(B=127,L=2^{23}\),关联到指数E和小数M

故:
\(x=argI(E,M)=(1+L/M​)×2^{E−B}\)

对x取对数:
\(log_2(x)=log_2[(1+\frac{M}{L} )\times 2^{E-B}]\)

泰勒近似:

\(log_2​(1+m)=m+α,m∈[0,1)\), \(\alpha\)为误差

\(log_2(x)=log_2[(1+\frac{M}{L} )\times 2^{E-B}]= \frac{(E+\frac{M}{L}) \times L}{L} +\alpha -B\)

而\((E+\frac{M}{L}) \times L\)正是32bits 二进制数decoding为整数

../all images/快速开平方根倒数算法(/i/l/?n=23&i=blog/3329763/202406/3329763-20240604100744997-719238169.webp)-20240511171551171.webp-20240511171551171.webp)

\(I(y)=R-\frac{1}{2}I(x)\)

\(y=argI(E_y,M_y)=(1+\frac{M_y}{L})*2^{E_y-B}\)

\(\alpha=Error(x)=log_2(1+x)-x, x∈[0,1)\)

源代码作者采取\(α=0.0450465\)

../all images/快速开平方根倒数算法(/i/l/?n=23&i=blog/3329763/202406/3329763-20240604100745043-1732476324.webp)-20240511172133421.webp-20240511172133421.webp)

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模块的使用,主要是对浮点数和整数进行打包和解析操作。让我解释一下各个参数的含义:

  1. struct.pack('f', y)

    • struct.pack(format, value)函数用于将值打包为指定格式的字节对象。
    • 'f'是格式化字符串,代表将值打包为浮点数。
    • y是要打包的值,即输入的浮点数。
  2. struct.unpack('i', ...)

    • struct.unpack(format, data)函数用于从字节对象中解析出值。
    • 'i'是格式化字符串,代表解析的值为整数。
    • ...是前面打包得到的字节对象,即浮点数y打包后的字节对象。
  3. struct.unpack('i', struct.pack('f', y))[0]

    • 这个表达式的含义是先将浮点数y打包为字节对象,然后再从字节对象中解析出整数值。
    • [0]表示取解析结果中的第一个值,因为struct.unpack返回的是一个元组。

综合起来,这行代码的作用是将浮点数y转换为字节对象(即二进制表示),然后再从字节对象中解析出整数值。这个操作是算法中的一个关键步骤,用于对输入的浮点数进行位操作和处理。

标签:inverse,frac,struct,浮点数,number,Carmack,root,字节
From: https://www.cnblogs.com/invo/p/18230258

相关文章

  • CMakeFile.txt通过sysroot方式后生成makefile报错
    怪不得博客园干不过别家,体验真的不太好。通过openwrite发布文章,其他平台都能发布,就博客园限制了,理由是文字少的文章限制发布到该平台。哎,这种行为当真是扶不起的阿斗。以后也不要太把博客园当回事了,迟早要关门的报错信息如下:--TheCcompileridentificationisunknown--T......
  • MySQL中:cmd下输入命令mysql -uroot -p 连接数据库错误
    目录问题cmd下输入命令mysql-uroot-p错误待续、更新中问题cmd下输入命令mysql-uroot-p错误解决配置环境变量:高级系统设置——环境变量——系统变量——path编辑——新建——MySQL.exe文件路径(如下图所示)phpstudy2018软件下,找到网站根目录,打开数据库目录:......
  • 安装fail2ban服务-防止用户暴力破解root密码
    安装fail2ban服务,防止用户暴力破解root密码(最多让试着登录5次,5次密码输错就封杀ip)[root@bogon~]#lsepel-release-6-8.noarch.rpm[root@bogon~]#rpm-ivhepel-release-6-8.noarch.rpm #或yum-yinstallepel-release[root@bogon~]#yuminstallfail2ban-y复制ja......
  • ESXI忘记root登陆密码
    环境:ESXI6.7.0目的:root密码忘记,需要重置准备工具:CentOS7系统的U盘启动或者Ubuntu系统的U盘启动①服务器通过U盘启动,进入shell命令行,出现下图,选择“Troubleshooting->”选择“RescueaCentOSsystem”输入“1”,然后回车即可进入shell命令行②挂载ESXI的目录,修改/etc/......
  • 解决Vue3项目使用多个根标签提示[vue/no-multiple-template-root]The template root r
    报错截图检查原因第一步:检查是否安装了 Vetur 插件 第二步:左下角设置图标 ==》设置第三步:进入设置页面搜索eslint把Vetur的验证模板,取消勾选 Validatevue-htmlinusingeslint-plugin-vue第四步:将错误提示页面关掉然后重新打开,即可正常显示......
  • Nginx企业级负载均衡:技术详解系列(12)—— 深入解析root、alias及location
    你好,我是赵兴晨,97年文科程序员。在生产服务器的Nginx配置中,我们总会遇到形形色色的配置方案。你是否曾注意到root和alias指令的巧妙应用?是否对那些五花八门的location匹配规则感到好奇?今天,咱们来聊聊Nginx配置中root和alias以及location的详细使用。root与aliasroot:指......
  • 一例APP绕过root检测解密
    一例APP绕过root检测解密前言最近在分析一款app时遇见了root检测,数据包加密,花了时间简单研究了一下,记录下学习的过程。 抛出问题打开app发现提示检测到设备为root设备,闪退。能看到提示,推测应该是java层的检测。拖进jadx发现是加固的。通过frida绕过检测java层常见......
  • Xperia 1iii 日版 免root 卸载系统程序
    一、开启开发者选项自行百度不再赘述二、安装adb并且配置到环境变量中自行百度不再赘述三、执行批处理文件新建一个bat文件把下面的内容复制进去然后双击执行。每一行代码会删除一个程序@echooffadbshellpmuninstall-k--user0jp.co.nttdocomo.lcsappadbshell......
  • SP14943 DRTREE - Dynamically-Rooted Tree 题解
    题目传送门前置知识树链剖分|线段树解法树剖换根,子树查询板子。类似换根DP的思路,我们发现换根后仅有祖先、子树、深度等会随祖先的变化而变化。设\(rt_{i}\)表示第\(i\)次操作的树根,\(x_{i}\)表示第\(i\)次操作的节点。接着进行大力分讨。当\(rt_{i}=x_{i}\)......
  • 【VMware vCenter】在不重启的情况下重置vCenter Server的root密码。
    VMware提供了一种方法,可以在不用重新启动vCenterServer进入grub引导至单用户模式的情况下重置root的密码,这种方法使用的是通过SSO管理员账号([email protected])登录到vCenterServer的VAMI管理界面,在右上角的操作菜单里提供更改root用户密码的选项。但是,上述方法仅适......