[英]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.