有人可以解释一下 maxBit 是什么吗?
Can someone explain what maxBit is?
我想了解下面的 maxBit 是什么以及它代表什么?
当我打印最小值和最大值时,我得到的数字对我来说毫无意义。
谢谢。
#include <stdio.h>
#include <math.h>
int main() {
union {double a; size_t b;} u;
u.a = 12345;
size_t max = u.b;
u.a = 6;
size_t min = u.b;
int maxBit = floor(log(max-min) / log(2));
printf("%d",maxBit);
return 0;
}
此代码似乎使用了可怕的拼凑。关于容忍使用编译器扩展或其他超出 C 标准的东西的代码,我是这里比较欢迎的参与者之一,但这段代码只是做了一些不必要的事情,没有明显的好处。它依赖于 size_t
是 64 位。在某些特定的 C 实现中它可能是 64 位的,这是为之编写的,但这不是可移植的,使用 64 位的 C 实现通常是现代的,现代实现应该支持 uint64_t
的 <stdint.h>
,这将是一个合适的类型。所以更好的代码会使用 uint64_t
.
除非代码中的这个问题和其他问题有一些非常令人惊讶的动机,否则它是低质量、糟糕的代码。不要使用它,并怀疑来自同一来源的任何代码。
也就是说,代码可能假定 IEEE-754 binary64 用于 double
,并且 max-min
给出了 12345 和 6 的表示之间的差异。log(max-min) / log(2)
找到max-min
的以二为底的对数,其整数部分将是更改的最高位的索引。对于12345,指数字段为1036。对于6,指数字段为1025。相差11(二进制1011),其中第一个设置位是指数字段的第3位。该字段在 binary64 格式中从第 62 位运行到第 52 位,因此指数字段中的第 3 位是表示的整个 64 位中的第 55 (52+3) 位。所以 maxBit 将为 55。但是,这没有明显的意义。知道第 55 位是 12345 和 6 的表示之间的差异中的最高位集没有多大价值。我熟悉各种 IEEE-754 位旋转黑客,但我不承认这一点。我希望没有人能在没有上下文的情况下告诉您更多相关信息,例如代码的来源或使用方式。
来自 C17 document,6.5.2.3 结构和联合成员,脚注 97:
If the member used to read the contents of a union object is not the
same as the member last used to store a value in the object, the
appropriate part of the object representation of the value is
reinterpreted as an object representation in the new type as described
in 6.2.6 (a process sometimes called “type punning”). This might be a
trap representation.
因此,当您存储 u.a = 12345
然后访问 size_t max = u.b
时,u.a
内存中的位模式被重新解释为 size_t
。因为,u.a
是double,所以用IEEE754格式表示。
max
和min
中存储的值是:
4668012349850910720 (0100000011001000000111001000000000000000000000000000000000000000-> IEEE754)
4618441417868443648 (01000000000110000000000000000000000000000000000000000000000000000000000-> IEEE754)
然后,max-min = 49570931982467072
,然后log(max-min)/log(2) = 55.460344
,然后floor(55.460344) = 55
。这就是输出 55 的原因。
PS: IEEE754格式有两种:单精度(32位)和双精度(64位)。请访问此网站IEEE754了解更多详情。
我想了解下面的 maxBit 是什么以及它代表什么?
当我打印最小值和最大值时,我得到的数字对我来说毫无意义。
谢谢。
#include <stdio.h>
#include <math.h>
int main() {
union {double a; size_t b;} u;
u.a = 12345;
size_t max = u.b;
u.a = 6;
size_t min = u.b;
int maxBit = floor(log(max-min) / log(2));
printf("%d",maxBit);
return 0;
}
此代码似乎使用了可怕的拼凑。关于容忍使用编译器扩展或其他超出 C 标准的东西的代码,我是这里比较欢迎的参与者之一,但这段代码只是做了一些不必要的事情,没有明显的好处。它依赖于 size_t
是 64 位。在某些特定的 C 实现中它可能是 64 位的,这是为之编写的,但这不是可移植的,使用 64 位的 C 实现通常是现代的,现代实现应该支持 uint64_t
的 <stdint.h>
,这将是一个合适的类型。所以更好的代码会使用 uint64_t
.
除非代码中的这个问题和其他问题有一些非常令人惊讶的动机,否则它是低质量、糟糕的代码。不要使用它,并怀疑来自同一来源的任何代码。
也就是说,代码可能假定 IEEE-754 binary64 用于 double
,并且 max-min
给出了 12345 和 6 的表示之间的差异。log(max-min) / log(2)
找到max-min
的以二为底的对数,其整数部分将是更改的最高位的索引。对于12345,指数字段为1036。对于6,指数字段为1025。相差11(二进制1011),其中第一个设置位是指数字段的第3位。该字段在 binary64 格式中从第 62 位运行到第 52 位,因此指数字段中的第 3 位是表示的整个 64 位中的第 55 (52+3) 位。所以 maxBit 将为 55。但是,这没有明显的意义。知道第 55 位是 12345 和 6 的表示之间的差异中的最高位集没有多大价值。我熟悉各种 IEEE-754 位旋转黑客,但我不承认这一点。我希望没有人能在没有上下文的情况下告诉您更多相关信息,例如代码的来源或使用方式。
来自 C17 document,6.5.2.3 结构和联合成员,脚注 97:
If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called “type punning”). This might be a trap representation.
因此,当您存储 u.a = 12345
然后访问 size_t max = u.b
时,u.a
内存中的位模式被重新解释为 size_t
。因为,u.a
是double,所以用IEEE754格式表示。
max
和min
中存储的值是:
4668012349850910720 (0100000011001000000111001000000000000000000000000000000000000000-> IEEE754) 4618441417868443648 (01000000000110000000000000000000000000000000000000000000000000000000000-> IEEE754)
然后,max-min = 49570931982467072
,然后log(max-min)/log(2) = 55.460344
,然后floor(55.460344) = 55
。这就是输出 55 的原因。
PS: IEEE754格式有两种:单精度(32位)和双精度(64位)。请访问此网站IEEE754了解更多详情。