2010-03-30 39 views
15

簡短而親切的版本:decimal.TryParse()下降前導 「1」

在一臺機器了大約100名試驗機decimal.TryParse()是將 「1.01」 到0.01


好吧,這聽起來很瘋狂,但忍受着我...

我們有一個客戶端應用程序,通過JSON與web服務進行通信,並且該服務返回一個十進制值作爲字符串,因此我們將它作爲字符串存儲在我們的模型對象中:

[DataMember(Name = "value")] 
public string Value { get; set; } 

當我們在屏幕上顯示該值時,它被格式化爲特定的小數位數。所以我們使用的過程是string - > decimal,然後是decimal - > string。

該應用程序目前正在進行最終測試,並在超過100臺機器上運行,其中這一切都正常工作。但在之一機器如果十進制值有一個前導'1',那麼它被替換爲零。我加了簡單的日誌記錄的代碼,所以它看起來是這樣的:

Log("Original string value: {0}", value); 
decimal val; 
if (decimal.TryParse(value, out val)) 
{ 
    Log("Parsed decimal value: {0}", val); 
    string output = val.ToString(format, CultureInfo.InvariantCulture.NumberFormat); 
    Log("Formatted string value: {0}", output); 
    return output; 
} 

在我的機器 - 任何其它客戶機 - 日誌文件輸出爲:

  • 原始字符串值:1.010000
  • 解析的十進制值:1.010000
  • 格式化字符串值:1.01

在缺陷機器的輸出是:

  • 原始字符串值:1.010000
  • 解析的十進制值:0.010000
  • 格式化字符串值:0.01

所以它會出現decimal.TryParse方法出錯。

的事情,我們已經試過:

  • 卸載並重新安裝客戶端應用程序
  • 卸載並重新安裝.NET 3.5 SP1
  • 的數字(以英語比較殘次機的區域設置(英國) )對一臺工作機器的 - 沒有區別。

有沒有人看過類似的東西或有任何建議?我很快就沒有想法...


當我輸入這個更多的信息進來:傳遞一個字符串值「10000」轉換。ToInt32()返回0,這樣也似乎放棄基於評論領先1


進一步的測試:

  • 1.01 - > 0.01
  • 111.01 - > 11.01
  • 123.01 - > 23.01
  • 231.01 - > 231.01
  • 01.01 - > 1.01

所以看起來它只會影響1s,只有它們是字符串的第一個字符。很奇怪,但至少它是一致的。

+1

奇怪。其他數字如「123」或「321」會發生什麼情況? – 2010-03-30 09:34:55

+0

機器壞RAM?你有沒有試過像memtest86運行的東西? – 2010-03-30 09:36:42

+0

這是一個非常糟糕的主意,但是如果你預先填充零...? – spender 2010-03-30 09:38:09

回答

16

我能夠重現您的結果。 考慮:

public NumberFormatInfo OneIsPositiveSignFormat() 
{ 
    NumberFormatInfo custom = new NumberFormatInfo(); 
    custom.PositiveSign = "1"; 
    return custom; 
} 

然後:

if (decimal.TryParse(value, NumberStyles.Number, OneIsPositiveSignFormat(), out val)) 

的事情是:區域設置不顯示你當前的積極的跡象,並且主要是:解析的數量,當你沒有設置文化。

值可能來自不同的地方:它可能來自注冊表作爲系統默認值,或默認值可能已被設置代碼:

CultureInfo customCulture = (CultureInfo)CultureInfo.InvariantCulture.Clone(); 
customCulture.NumberFormat = OneIsPositiveSignFormat(); 
Thread.CurrentThread.CurrentCulture = customCulture; 
+1

有趣的答案,但它提出的問題是,如果區域設置不允許您設置正號,並且OP的區域設置與其他機器相同,那麼正號如何改變?我並不反對你,它完全符合這些例子,我只是好奇而已。 – 2010-03-30 11:06:55

+2

我們有一個贏家!在他的機器上運行以下代碼:Console.WriteLine(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PositiveSign);並輸出「1」。現在,只需要弄清楚如何改變這一點... – 2010-03-30 11:18:57

+0

我敢打賭,這是一個第三方程序,做到了這一點。什麼怪物。 – Kugel 2010-03-30 11:27:43

-1

看看如何設置這臺電腦的區域設置,它可能是「。」被設置爲千位分隔符而不是小數點分隔符。嘗試使用Decimal.TryParse(String,NumberStyles,IFormatProvider,輸出Decimal val)並傳遞用小數點分隔符「。」創建的NumberFormatInfo。

+2

OP已經表示在區域設置中沒有區別 - 如果輸入1.000時,如果輸入千位分隔符,它會給出1000,而不是0。 – 2010-03-30 09:39:03