簡體   English   中英

.Net 中的往返格式說明符“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.

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