我希望strtol("ffffffffffffffff", NULL, 16)return-1和strtol("7fffffffffffffff", NULL, 16)return LONG_MAX,因為linux 手冊頁的第一句話似乎暗示 strtol 回傳有符號的長。第二次呼叫確實回傳了預期的結果。但是第一個電話回傳LONG_MAX!就像,輸入的十六進制字串甚至不一樣。好像這還不夠令人困惑,strtol("8000000000000000", NULL, 16)我希望 return LONG_MIN,回傳與前兩個呼叫相同的值,LONG_MAX。對于前兩個呼叫,我認為 strtol 忽略了輸入字串中的最高有效位,但第三個呼叫反駁了這個假設。
這是一些奇怪的鑄造案例還是我將數學現實與 C 現實混合在一起?
這是我的源代碼:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[]) {
long x = strtol(argv[1], NULL, 16);
printf("%ld\n", x);
return 0;
}
我gcc scratch.c在 Ubuntu 上進行編譯,我通過將十六進制字串作為命令列引數傳遞來獲得結果。例如:
./a.out ffffffffffffffff // gives LONG_MAX
./a.out 8000000000000000 // gives LONG_MAX
./a.out 7fffffffffffffff // gives LONG_MAX
uj5u.com熱心網友回復:
strtol("ffffffffffffffff", NULL, 16)請求strtol將“ffffffffffffffff”解釋為十六進制整數。它不要求strtol將其解釋為單個位元組的十六進制值規范,然后將這些位元組重新解釋為long.
十六進制整數 ffffffffffffffff 16是 18,446,744,073,709,551,615 = 2 64 -1。在您的 C 實作中,a 中可表示的最大值long是 9,223,372,036,854,775,808 = 2 63 -1。
的檔案strtol,在 C 2018 7.22.1.4 8 中說,如果該值高于或低于可表示值的范圍,LONG_MAX或者LONG_MIN分別回傳:
、
strtol、strtoll和函式回傳轉換strtoul后strtoull的值(如果有)。如果無法執行轉換,則回傳零。如果正確的值在可表示值的范圍之外,LONG_MIN,LONG_MAX,LLONG_MIN,LLONG_MAX,ULONG_MAX, 或者ULLONG_MAX回傳(根據回傳型別和值的符號,如果有的話),宏的值ERANGE存盤在errno.
在您閱讀并理解其檔案之前,最好不要呼叫,尤其是不要依賴任何例程。尤其是當例程沒有按預期運行時,請閱讀其檔案。
uj5u.com熱心網友回復:
根據 C 標準(7.22.1.4 strtol、strtoll、strtoul 和 strtoull 函式)
8 strtol、strtoll、strtoul 和 strtoull 函式回傳轉換后的值(如果有)。如果無法執行轉換,則回傳零。如果正確值超出可表示值的范圍,則回傳 LONG_MIN、LONG_MAX、LLONG_MIN、LLONG_MAX、ULONG_MAX 或 ULLONG_MAX(根據值的回傳型別和符號,如果有),宏 ERANGE 的值為存盤在 errno 中。
這些字串文字"ffffffffffffffff"并"8000000000000000"解釋為正數不能在有符號型別的物件中表示long
uj5u.com熱心網友回復:
您系統上的long型別似乎有 64 位,最大正值為 2 63 -1(LONG_MAX在您的平臺上),以十六進制表示為7fffffffffffffff. 任何大于此的值都將導致strtol回傳LONG_MAX并設定errno為ERANGE。
這就是你觀察到的ffffffffffffffff和8000000000000000。
請注意,十六進制字串的開頭可以有一個可選的前綴0xor 0X。
您可以使用 決議 unsigned long 值strtoul,最大值為 2 64 -1(ULONG_MAX在您的平臺上),以十六進制表示為ffffffffffffffff。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/448233.html
上一篇:在C中創建沒有malloc的鏈表
