簡體   English   中英

將uint64_t轉換為double后出現意外結果

[英]Unexpected result after converting uint64_t to double

在以下代碼中:

#include <iostream>

...

uint64_t t1 = 1510763846;
uint64_t t2 = 1510763847;
double d1 = (double)t1;
double d2 = (double)t2;
// d1 == t2 => evaluates to true somehow?
// t1 == d2 => evaluates to true somehow?
// d1 == d2 => evaluates to true somehow?
// t1 == t2 => evaluates to false, of course.
std::cout << std::fixed << 
        "uint64_t: " << t1 << ", " << t2 << ", " <<
        "double: " << d1 << ", " << d2 << ", " << (d2+1) << std::endl;

我得到這個輸出:

uint64_t: 1510763846, 1510763847, double: 1510763904.000000, 1510763904.000000, 1510763905.000000

我不明白為什么。 這個答案: 可以存儲在double中的最大整數表示最多2 ^ 53(9007199254740992)的整數可以存儲在一個double精度而不會丟失精度。

當我開始用雙打計算時,我實際上會出錯,所以這不僅僅是打印問題。 (例如1510763846和1510763847均給出1510763904)

雙倍可以添加到然后出來正確也是非常奇怪的(d2 + 1 == 1510763905.000000)

基本原理:我將這些數字轉換為雙數,因為我需要在Lua中使用它們,它只支持浮點數。 我確定我正在使用double作為lua_Number類型編譯Lua lib,而不是float

std::cout << sizeof(t1) << ", " << sizeof(d2) << std::endl;

輸出

8, 8

我正在使用VS 2012與目標MachineX86,工具包v110_xp。 浮點模型“精確(/ fp:精確)”

附錄

在回復的人和本文的幫助下, 為什么在特定的Visual Studio 2008項目中錯誤地添加了雙打? ,我已經能夠找出問題所在。 庫正在使用_set_controlfp,_control87,_controlfp或__control87_2等函數將可執行文件的精度更改為“single”。 這就是為什么uint64_t轉換為double的行為就好像它是一個浮點數。

在執行文件搜索上述函數名稱和“MCW_PC”(用於精確控制)時,我發現可能設置了以下庫:

  • Android NDK
  • 提高::數學
  • 提高::數字
  • DirectX(我們使用2010年6月)
  • FMod(非EX)
  • Pyro粒子引擎

現在我想重新解釋一下我的問題:

如何確保每次都能正確地從uint64_t轉換為double ,而不是:

  1. 必須在每次發生可能的轉換時調用_fpreset()(考慮函數參數)
  2. 不得不擔心庫的線程在我的_fpreset()和轉換之間改變浮點精度?

天真的代碼將是這樣的:

double toDouble(uint64_t i)
{
    double d;
    do {
        _fpreset();
        d = i;
        _fpreset();
    } while (d != i);
    return d;
}

double toDouble(int64_t i)
{
    double d;
    do {
        _fpreset();
        d = i;
        _fpreset();
    } while (d != i);
    return d;
}

這個解決方案假設一個線程搞亂浮點精度兩次的幾率是天文數字小。 問題是,我正在使用的值是代表真實世界價值的計時器。 所以我不應該冒任何風險。 這個問題有靈丹妙葯嗎?

從ieee754浮點轉換看起來你的double實現實際上是浮點數,當然這是標准所允許的,它規定了sizeof double >= sizeof float

最准確的1510763846表示是1.510763904E9。

暫無
暫無

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

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