gpt4 book ai didi

c++ - line 是什么意思?

转载 作者:行者123 更新时间:2023-12-01 14:34:40 25 4
gpt4 key购买 nike

float sqrt_approx(float z) {
int val_int = *(int*)&z; /* Same bits, but as an int */
/*
* To justify the following code, prove that
*
* ((((val_int / 2^m) - b) / 2) + b) * 2^m = ((val_int - 2^m) / 2) + ((b + 1) / 2) * 2^m)
*
* where
*
* b = exponent bias
* m = number of mantissa bits
*
* .
*/

val_int -= 1 << 23; /* Subtract 2^m. */
val_int >>= 1; /* Divide by 2. */
val_int += 1 << 29; /* Add ((b + 1) / 2) * 2^m. */

return *(float*)&val_int; /* Interpret again as float */
}

我正在阅读一篇关于计算平方根方法的维基文章。我来到这段代码并在这一行加注星标。

 int val_int = *(int*)&z; /* Same bits, but as an int */

为什么他们将 z 转换为 int 指针然后取消引用它?为什么不直接说 val_int = z;为什么要使用指针? PS:我是初学者。

最佳答案

这称为类型双关。这种特殊用法违反了 strict aliasing规则

通过获取浮点值 z 的地址,并将其重新解释为整数值的地址,作者试图访问表示此 float 的内存字节,但为了方便 int.

这和int val_int = z 不一样;这会将浮点值转换为整数,从而在内存中产生不同的位。

除了严格的别名问题之外,这里的一个大问题是代码对任何目标系统上的int 大小字节顺序进行了假设。因此,代码不可移植。

访问 z 字节的正确方法是 char 数组:

const uint8_t* zb = (const uint8_t*)&z;

然后您可以从这些具有特定字节顺序的结构中构造一个适当大小的整数:

uint32_t int_val = ((uint32_t)zb[0]) |
(((uint32_t)zb[1]) << 8) |
(((uint32_t)zb[2]) << 16) |
(((uint32_t)zb[3]) << 24);

这类似于一个更简单的调用,假设您在小端系统上:

uint32_t int_val;
memcpy(&int_val, &z, sizeof(int_val));

但这不是全貌,因为 float 字节序是标准化的(至少假设 IEEE 754 您的代码是针对它的)而 int 是系统相关的.

到这里,整个例子就崩溃了。在基础层面上,原始代码是(假设)基于技巧的快速近似。如果你想“正确”地完成这些技巧,它就会变得有点乱。

关于c++ - line 是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62785645/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com