[英]Why is “double” represented as integer?
void foo(double a) {
...
}
在main()
我将107.0
传递给foo
作为其参数。 然后,我使用gdb来检查p /ta
的a
的二进制表示形式,这就是我得到的:
$1 = 1101011
这个结果对我来说似乎很奇怪。 这是INTEGER 107的二进制表示但这里的类型a
被定义为double
和我们传递的参数107.0
。 而且我们知道双精度数具有不同的二进制表示形式(整数)。
谁能解释为什么a
具有整数二进制表示而不是double? 编译器做任何有趣的事情吗?
您告诉gdb将其打印为二进制整数。
p /t a
如果要查看浮点版本,请使用
p /f a
x将值的位视为整数,并以十六进制打印整数。
d打印为带符号十进制的整数。
用无符号十进制打印为整数。
o打印为八进制整数。
t以二进制形式打印为整数。 字母“ t”代表“两个”。 (2)
a以地址形式打印,既可以是绝对的十六进制形式,也可以是距最近的前一个符号的偏移量。 您可以使用以下格式来发现未知地址的位置(以什么功能):
c将其视为整数并将其打印为字符常量。
f将值的位视为浮点数,并使用典型的浮点语法进行打印。
例如,要以十六进制打印程序计数器(请参阅寄存器部分),请键入
p/x $pc
双精度数以2的幂表示,与整数略有不同。 不用多说,107就是1.101011 *(2 ^ 6)=1101011。gdb可能只显示最后一个结果,而无缘无故为您提供完整的64位表示。
我不太熟悉gdb,但是当您写“ d”时,它可能会认为您明确表示整数
考虑:
double foo = 1.0;
printf("%d",foo);
c会让您感到困惑,因为您告诉它给它一个整数,但实际上给它一个双精度数。
有几种方法可以从gdb命令行打印变量的值。
print对表达式有效,并且会像C一样进行一些隐式转换。
您的示例中的p /ta
将a的值转换为整数,并以2为底打印。
您想查看a
的位模式,因此print
有一些选项:
uint64_t
为与双uint64_t
长度(在您的示例中可能是unsigned long long
或uint64_t
长度相同的无符号整数类型的指针,然后取消引用。 (gdb) p /t *(uint64_t *)&a
$6 = 100000001011010110000000000000000000000000000000000000000000000
{uint64_t}
更简洁地完成同一件事。 (gdb) p /t {uint64_t}&a
$7 = 100000001011010110000000000000000000000000000000000000000000000
x显示给定地址的数据,您可以指定数据类型。 /g
表示8字节整数。
(gdb) x /tg &a
0x7fffffffded8: 0100000001011010110000000000000000000000000000000000000000000000
如果您使用优化,则a
可能在寄存器中,并且您将无法获取其地址,因此上述方法均无效。
(gdb) p {uint64_t}&a
Address requested for identifier "a" which is in register $ymm0
但是gdb
支持使用类似于数组C联合的语法以各种格式打印AVX寄存器的内容。
(gdb) p $ymm0
$1 = {v8_float = {0, 3.41796875, 0, 0, 0, 0, 0, 0},
v4_double = {107, 0, 0, 0}, v32_int8 = {0, 0, 0, 0, 0, -64, 90,
64, 0 <repeats 24 times>},
v16_int16 = {0, 0, -16384, 16474, 0 <repeats 12 times>},
v8_int32 = {0, 1079689216, 0, 0, 0, 0, 0, 0},
v4_int64 = {4637229872563879936, 0, 0, 0},
v2_int128 = {0x0000000000000000405ac00000000000, 0x00000000000000000000000000000000}}
(gdb) p /t $ymm0.v4_int64[0]
$2 = 100000001011010110000000000000000000000000000000000000000000000
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.