簡體   English   中英

如何將C#double修剪為將在sqlite數據庫中存儲的值?

[英]How can I 'trim' a C# double to the value it will be stored as in an sqlite database?

我注意到當我在sqlite數據庫中存儲雙值(例如x = 0.56657011973046234 ,然后在以后檢索它時,我得到y = 0.56657011973046201 根據sqlite規范.NET規范 (我最初都不打算閱讀:)這是預期和正常的。

我的問題是,雖然高精度並不重要,但我的應用程序處理用戶輸入/選擇代表基本3D信息的雙打,然后對它們運行模擬以查找結果。 此輸入可以保存到sqlite數據庫,以便重新加載並在以后重新運行。

之所以出現這種混淆,是因為新創建的一系列輸入顯然會在存儲和重新加載后以相同的輸入方式略微模擬(因為雙值已經改變)。 這是合乎邏輯的,但不是理想的。

我還沒有談到如何處理這個問題,但與此同時我想將用戶輸入限制/鉗位到可以精確存儲在sqlite數據庫中的值。 因此,如果用戶輸入0.56657011973046234 ,則實際上將其轉換為0.56657011973046201

但是,鑒於一個數字,我無法弄清楚數據庫中存儲了什么值,而不是實際存儲和從數據庫中檢索它,這看起來很笨拙。 有沒有確定的方法這樣做?

答案可能是將雙值存儲為17個有效數字字符串。 看看SQLite如何處理實數與文本之間的區別(為簡單起見,我將使用命令行界面進行說明):

sqlite> create table t1(dr real, dt varchar(25));
sqlite> insert into t1 values(0.56657011973046234,'0.56657011973046234');
sqlite> select * from t1;
0.566570119730462|0.56657011973046234

以真正的親和力存儲它是導致問題的原因 - SQLite只能為您提供15位數的近似值。 如果您將其存儲為文本,則可以使用C#程序檢索原始字符串並將其轉換回原始字符串。

假設SQL Lite和.NET都正確地實現了IEEE規范,如果在兩端使用相同的浮點類型,則應該能夠獲得相同的數值結果(因為從數據庫傳遞時不應更改該值)到C#,反之亦然)。

目前,您在SQL Lite中使用8字節IEEE浮點(單個)(*),在C#中使用16字節浮點(雙精度)。 C#中的float類型對應於8字節IEEE標准,因此使用此類型而不是double可以解決問題。

(*)SQL Lite文檔說REAL是浮點值,存儲為8字節IEEE浮點數

Double round具有一個帶有參數的實現,該參數指定了位數。 用它來舍入到14位數(比方說):rval = Math.Round(Val,14)

然后在從數據庫接收值時進行舍入,並在模擬開始時,即。 那么在價值匹配?

詳情如下:

http://msdn.microsoft.com/en-us/library/75ks3aby.aspx

另一個想法是,如果你不是在比較數據庫中的值,只是存儲它們:為什么不簡單地將它們存儲為二進制數據? 那么所有的比特都會被逐字存儲和恢復?

您可以使用字符串在數據庫中存儲#。 就個人而言,我已經完成了在存儲之前和從db(使用numeric())獲取之后winwaed建議舍入的內容。

我記得被銀行家四舍五入燒掉,但可能只是因為不符合規范。

您可以將double存儲為字符串,並在將double轉換為字符串時使用往返格式,保證在解析時生成相同的值:

string formatted = theDouble.ToString("R", CultureInfo.Invariant);

如果您希望十進制輸入值進行往返,則必須將它們限制為15位有效數字。 如果您希望SQLite內部雙精度浮點值往返,那么您可能會失敗; 這需要打印至少17個有效數字,但從我所知,SQLite打印它們最多15( 編輯 也許SQLite專家可以確認這一點? 我只是閱讀源代碼並追蹤它 - 我是正確,精度限制在15位。)

我在Windows上的SQLite命令界面中測試了您的示例。 我插入了0.56657011973046234,然后選擇返回0.566570119730462。 在C中,當我將0.566570119730462指定為雙精度並將其打印為17位數時,我得到0.56657011973046201; 這與你從C#獲得的價值相同。 0.56657011973046234和0.56657011973046201映射到不同的浮點數,因此換句話說,SQLite double不會往返。

暫無
暫無

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

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