简体   繁体   English

使用定点而不是浮点的快速反平方根

[英]Fast inverse square root using fixed point instead of floating point

I am trying to implement Fast Inverse Square Root for a fixed point number, but I'm not getting anywhere.我正在尝试为定点数实现快速平方根平方根,但我没有得到任何结果。

I am trying to follow exactly the same principle as the article, except instead of writing the number in the floating point format x = (-1) ^ s * (1 + M) * 2 ^ (E-127) , I am using the format x = M * 2 ^ -16 , which is a 32-bit fixed point number with 16 decimal bits and 16 fractional bits.我试图遵循与文章完全相同的原则,除了我使用的是浮点格式x = (-1) ^ s * (1 + M) * 2 ^ (E-127)而不是写数字格式x = M * 2 ^ -16 ,它是一个 32 位定点数,有 16 个小数位和 16 个小数位。

The problem is that I cannot find the value of the "magic constant".问题是我找不到“魔术常数”的值。 According to my calculations, it doesn't exist, but I'm not a mathematician and I think I'm doing everything wrong.根据我的计算,它不存在,但我不是数学家,我认为我做的一切都是错的。

To solve Y = 1 / sqrt (x), I used the following reasoning (I don't know if it is correct).为了解决Y = 1 / sqrt(x),我使用了以下推理(我不知道它是否正确)。

In the original code we have that Y0 for approximation of newton is given by:在原始代码中,牛顿近似的 Y0 由下式给出:

i = 0x5f3759df - (i >> 1);

Which means that we will have as a result a floating point number given by:这意味着我们将得到一个浮点数,由下式给出:

y0 = (1 + R2 - M / 2) * 2 ^ (R1 - E / 2);

This is because the operation >> divides exponent and mantissa by 2, and then we perform a subtraction of the numbers as integers.这是因为运算>>将指数和尾数除以 2,然后我们将数字作为整数进行减法。

Following the steps shown in the article, I set the format of x to:按照文章中显示的步骤,我将 x 的格式设置为:

x = M * 2 ^ -16

In an attempt to perform the same logic, I try to define Y0 for:为了尝试执行相同的逻辑,我尝试将 Y0 定义为:

Y0 = (R2 - M / 2) * 2 ^ (R1 - (-16/2));

I'm trying to find a number, which can minimize the error given by:我正在尝试找到一个数字,它可以最大限度地减少由以下给出的错误:

error = (Y - Y0) / Y

Regardless of the value of R1, I can do shift operations to correct the exponent value of my final result, having the correct result at a fixed point.无论 R1 的值如何,我都可以进行移位操作来纠正最终结果的指数值,从而在固定点获得正确的结果。

Where am I wrong?我哪里错了?

It can't be done.这是不可能的。

The fast inverse sqrt is due to the floating point representation, that has already split the number into powers of two (exponent) and the significant.快速逆 sqrt 是由于浮点表示,它已经将数字分成了 2 的幂(指数)和显着性。

It can be done.可以办到。

With the same tricks as done for floating points, it's possible to convert your fixed point into 2^exp * x.使用与浮点相同的技巧,可以将定点转换为 2^exp * x。 Given uint32_t a , uint8_t exp = bias- builtin_count_leading_zeros(a) ;给定uint32_t a , uint8_t exp = bias- builtin_count_leading_zeros(a) ; uint32_t b = a << exp , with the constants (and domain of a ) so carefully chosen, that there will be no underflows or overflows. uint32_t b = a << exp ,常数(和a域)经过精心挑选,不会出现下溢或上溢。

Thus, you will actually have a custom floating point representation, which is tailored for this specific purpose, omitting the sign bit at least and having the best possible number of bits for the exponent, which might as well be 8.因此,您实际上将有一个自定义浮点表示,它是为此特定目的量身定制的,至少省略符号位并为指数提供尽可能多的位数,也可能是 8。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM