簡體   English   中英

C如何從無符號整數中檢索精確的雙精度值(精度)

[英]C how to retrieve exact double value (precision) from a unsigned integer

我有一個要進行反向工程的校驗和,我已經知道在最初知道用於創建校驗和的原始初始值后如何保持校驗和的生成。

到目前為止,我知道校驗和是使用雙數據類型數學方程式生成的。

計算得出的校驗和的最終值是一個無符號整數,但在此之前,它已從double轉換為unsigned long long aka(無符號__int64)。

我正在嘗試做的是將無符號整數重新取回double數據類型中的相同值,以進行撤消校驗和以檢索原始初始值的下一步。

在計算校驗和時,這里是它以double數據類型生成的值。 3083570000.3115764創建校驗和0xB7CB8B50

我不認為這是一場有損失的對話,因此即使它從8字節的兩倍轉換為4字節的整數校驗和,也沒有任何損失。 為什么? 因為double值始終是通過乘以4294967295.0來創建的,我認為這只是消除了尾隨的4個字節(如移位)。

因此,我要檢索的double值必須除以4294967295.0 ,才能將原始雙精度值精確地返回到最后一位。

問題是我不能正確地對它進行除法,因為它不能精確到最后一個小數點。.我知道在使用浮點數學運算時,使用IEEE浮點廢話也不是100%准確,但是我不在乎只是嘗試以與最初創建時相同的方式來扭轉這種情況。

輸出說原始校驗和加倍為0.71794958809146792
0.71794958809146792 * 4294967295.0 = 3083570000.3115761849416764
數據包中發送的答案是0xb7cb8b50

如果我手動將無符號整數0xb7cb8b50unsigned __int64 ,它應該看起來像這樣0x00000000b7cb8b50

它是如何在代碼中生成的原始雙倍格式應如下所示,在將其附加到數據包之前,我使用了相同的密鑰來重新創建相同的條件以首先進行校驗和,並且它應如下所示
Real ANSWER = 3083570000.3115764

所以
0x00000000b7cb8b50 should equals = 3083570000.3115764 double

我的反向代碼如下所示

unsigned int checksum = 0xb7cb8b50;
double test1 = (double)(unsigned __int64)checksum;
double test2 = double(checksum);
double test3 = static_cast<double>(checksum);
double test4 = *((double*)(void*)&checksum);

上面的代碼有幾個小數位錯誤。

test1 returns = 3083570000.0000000
test2 returns = 3083570000.0000000
test3 returns = 3083570000.0000000
test4 returns = 1.523486003547e-314#DEN

如何獲得額外的.3115764也是我的問題。

double數的小數部分(在小數點后)分配給整數時會丟失。

進行反向操作(將結果int分配為double ),小數部分將為0。因此無法恢復回double數的原始值。

在以下代碼的輸出中,可以看到double值如何存儲在內存中(最高有效32位不為0):

double initial = 0.71794958809146792 * 4294967295.0;
uint64_t rawValue = *(uint64_t*)&initial;
uint32_t checksum = (uint32_t)initial;
printf("initial: %f 0x%llx\n", initial, rawValue);
printf("after:   %u 0x%x\n", checksum, checksum);
// Prints
// initial: 3083570000.311576 0x41e6f9716a09f86f
// after:   3083570000 0xb7cb8b50

嘗試將原始int值轉換為double (例如*((double*)(void*)&checksum) )是不正確的操作,它甚至可能訪問不屬於checksum內存(如果int大小為4個字節)。

有關double表示的更多信息,請參見:

https://zh.wikipedia.org/wiki/Double-precision_floating-point_format

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM