[英]How to convert fractional part of double to string or fractional part of double to integer using c without changing exact value
[英]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
如果我手動將無符號整數0xb7cb8b50
為unsigned __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.