[英]64 vs 32 bit double parsing issue with the round-trip format specifier “R”
[英]Failure of the Round-trip format specifier “R” in .Net
文檔建議我使用G17
而不是R
,因為R
有時無法往返。
然而, (1.0/10).ToString("G17")
給出了"0.10000000000000001"
,這非常可怕。 而往返格式似乎工作得很好(並給出"0.1"
)。 我很高興花幾個 cpu 周期來獲得更美觀的結果。 但潛在的往返故障更令人擔憂。
對於哪種(雙)值, R
無法往返? 有多嚴重? .Net 版本(我們在 Net Framework 4.72 和 NetCore 3.1 上運行)會影響事情嗎? 在一個平台上寫作並在另一個平台上閱讀是否會使往返失敗更頻繁?
我們正在考慮首先將 double 寫入R
,解析以檢查往返,只有在失敗時才回退到G17
。 有沒有更好的方法來獲得格式良好、可靠的結果?
這里的往返是將轉換為字符串的數值解析回相同的數值。
OP 對(1.0/10).ToString("G17")的失望給出了 "0.10000000000000001",這非常可怕。 是對往返成功的錯誤評估。 中間串只是往返行程的一半。
Double
精確編碼大約 2 64 個不同的值。 所有可編碼值都是一些有限的整數* 2 some_power 。 0.1不是其中之一。 1.0/10 使數學商為 0.1,但Double
值略有不同。 最近的Double
值和它的兩個壁櫥Double
鄰居:
Before 0.099999999999999991673...
0.100000000000000005551...
After 0.100000000000000019428...
OP report 0.10000000000000001
Digit count 12345678901234567
OP 的例子應該是 <(0.100000000000000005551).ToString("G17") 給出 "0.10000000000000001"> 這是好的。
使用G17
打印Double
提供 17 位有效數字,足以成功往返。
對於哪種(雙)值,R 無法往返? 有多嚴重?
為此,我繼續回憶。 R
有時使用少於 17 個有效數字(如 15)來形成中間字符串。 用於確定位數的算法有時會有點短,因此“某些情況下無法成功往返原始值”。
使用G17
始終有效。 對於某些值,小於 17 也會起作用。 G17
正是在這種情況下。 少於 17 位數字會起作用並提供更令人愉悅、更短的中間字符串。
令人愉悅的人類可讀字符串不是往返的目標。 目標是在從值到字符串到值后形成相同的Double
,即使中間字符串在某些情況下有額外的數字。
有沒有更好的方法來獲得格式良好、可靠的結果?
“格式良好”是往返的額外負擔。 MS 嘗試使用R
這樣做,但在某些情況下失敗了,寧願保留相同的損壞功能而不是修復它。
OP 明智的做法是避免該路徑並放棄格式良好的中間字符串的目標,並專注於獲取最終相同值的往返目標。
使用G17
。
我們正在考慮首先將 double 寫入 R,解析以檢查往返,只有在失敗時才回退到 G17。
如果正確完成,那將起作用。 要評估正確性,請使用許多值測試您的代碼,並發布它和用於代碼審查的測試工具。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.