2017-07-28 73 views
2

我有.net(4.6.1)中的場景解析6dp浮點值的字符串表示形式產生不同的結果32和64位模式。64 vs 32位雙向解析問題與往返格式說明符「R」

[Fact] 
public void ParseTest() 
{ 
    var numText = "51.580133"; 
    double.Parse(numText) 
     .ToString("R") 
     .Should().Be(numText); 
} 

此測試通過在32位模式,但對於64位模式中失敗所產生的文本是:「51.580132999999996」

我期望的舍入問題像這樣經由一個衍生無理數或數字等式,但這裏浮點的長度和精度沒有模糊之處。

這是在一個較舊的系統內,因此將所有內容更改爲十進制都需要花費大量精力。

問題:

  1. 爲什麼會出現這種情況?
  2. 有什麼選擇可靠地將此值舍入/截斷爲6dp?

更新 這工作,併產生不同的輸出的ToString( 「G6」):

[Fact] 
public void ParseText() 
{ 
    var numText = "51.580133"; 
    double.Parse(numText) 
     .ToString("G8") 
     .Should().Be(numText); 
} 
+1

那麼,你認爲問題出在解析或格式化?請記住,最接近51.580133的「double」*就是* 51.58013299999999645706338924355804920196533203125。 –

+1

[MSDN](https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings#the-round-trip-r-format-specifier):_「如果該值被成功解析回相同的數值,則使用通用格式說明符格式化該值。如果該值未成功解析回相同的數值,則使用雙精度的17位精度格式化該值「_ –

回答

5

我發現這個有趣的問題來自微軟這或許可以解釋這個問題

在某些情況下,使用「R」標準數字格式字符串格式化的Double值如果使用 /平臺進行編譯,則不會成功往返:x64或/ platform:anycpu開關並在64位sy上運行莖。

要解決此問題,可以使用 「G17」標準數字格式字符串來格式化Double值。以下示例使用帶有Double值的 「R」格式字符串,該值不會成功往返 ,並且還使用「G17」格式字符串成功地將原始值往返 。

的評論和實例可以在這裏找到:https://msdn.microsoft.com/en-us/library/kfsatb94(v=vs.110).aspx

+1

哇...這是一個非常可怕的錯誤:( –