我正在制作一個將任何數字(int64_t、uint64_t、double 以及后來的十六進制數字)轉換為字串的函式。我分別為它們撰寫了 3 個作業函式,但現在我試圖將它放在一個函式中。我搜索了一下如何在 C 中執行此操作(我對 C 比較陌生),發現我可以使用 void 指標來執行此操作。我需要在沒有 C 庫的情況下執行此操作,因為這是我正在制作的愛好作業系統。
這就是我目前正在檢查它是什么型別的數字的方式:
const char* to_string(void* value)
{
double val = *(double*)value;
if (val == (int64_t)val) {
return int_to_string((int64_t)val);
}
else
{
// double to string conversion.
}
}
但是當我放入一個 int64_t 或 uint64_t 空指標時,它總是回傳 0.00000,我不完全理解。
我在一個非常小的代碼片段中重現了這個問題:
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
int main(){
int64_t testNum = 2390874;
void* value = &testNum;
double val = *(double*)value;
printf("%f", val);
return 0;
}
我期待看到列印的數字,但事實并非如此。我懷疑我犯了一些初學者的錯誤,因為 C 對我來說是新手。非常感謝您的幫助,如果您需要更多資訊,請告訴我。
uj5u.com熱心網友回復:
值 2,390,874 在double格式中不是由以與int64_t.
以下是示例代碼的一些解釋:
int64_t testNum = 2390874;
這表示以用于的格式對 2,390,874 進行編碼并將int64_t其存盤在為testNum. 使用十六進制表示位,這會將 00 00 00 00 00 24 7B 5A 放入記憶體中。
void* value = &testNum;
這表示獲取為 保留的記憶體地址testNum,將其轉換為 ,并將其void *存盤在value.
double val = *(double*)value;
這表示將地址轉換value為double *,使用它來訪問記憶體,并以double格式解釋那里的位。C 標準沒有定義以這種方式進行重新解釋。但是,我將解釋假設您的 C 實作會發生什么。
在 IEEE-754 binary64 最常用的格式中double,第一位編碼符號(0 表示 ,1 表示 -),接下來的 11 位編碼指數和一位有效數,其余 52 位編碼其余的有效數字。(有效數字是浮點數的小數部分。)
在 00 00 00 00 00 24 7B 5A 中,第一位是 0,所以它編碼一個 符號。接下來的 11 位為零。這對指數 -1022 進行編碼,表示 2 -1022的縮放,并且它還指示有效數字的前導位是 0。(有效數字是浮點表示的小數部分。)其余位以 24 結尾在圖7B 5A中,對有效數字2,390,874?2 -52進行編碼。(格式中內置了縮放 2 ?52 。)
因此,編碼的數字為 2 -1022 ?2,390,874?2 -52 = 2,390,874?2 -1074,約為 1.1812487069350?10 -317。
當你用 格式化它時%f,它會顯示為“0.000000”,因為它太小了。如果你用 格式化它%.99f,它將在一個好的 C 實作中顯示為“1.18124870693504449006160973608001590543193999051572110682125774306312005276915307940719688096129009e-317”。
總之,您無法通過單獨檢查這些位來測驗記憶體中的位是否代表一個int64_t或double。相同的位編碼不同型別的不同值。型別資訊必須單獨傳達。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/522238.html
標籤:C整数双倍的
上一篇:為什么沒有回傳值?
下一篇:存盤的聯合和值
