[英]Why casting big double value in sbyte returns 0 in C#?
我實際上在未經檢查的上下文中測試了 C# 中的轉換行為。 就像文檔所說的那樣,在未經檢查的上下文中,演員表總是成功的。 但有時,在特定情況下,從一種特定類型到另一種類型的轉換會產生意想不到的結果。
例如,我測試了三個“double to sbyte”類型轉換:
var firstCast = (sbyte) -129.83297462979882752; // Result : 127.
var secondCast = (sbyte) -65324678217.74282742874973267; // Result : 0.
var thirdCast = (sbyte) -65324678216.74282742874973267; // Result : 0.
需要明確的是,第二個和第三個雙secondDouble - firstDouble = 1
之間的差異僅為1
( secondDouble - firstDouble = 1
)。 在這種情況下,對於任何“大”雙精度值,轉換結果似乎總是0
。
我的問題是:為什么第二次和第三次轉換結果為0
? 我在 C# 文檔中搜索了答案,但沒有找到。
我使用 .Net Framework 4.7.2 測試了上述內容。
根據C# 語言規范,
對於從 float 或 double 到整數類型的轉換,處理取決於發生轉換的溢出檢查上下文:
不使用checked
或unchecked
操作符,默認溢出檢查上下文是unchecked,所以我們看:
在未經檢查的上下文中,轉換總是成功,並按如下方式進行。
如果操作數的值為 NaN 或無窮大,則轉換的結果是目標類型的未指定值。
否則,源操作數將向零舍入到最接近的整數值。 如果此整數值在目標類型的范圍內,則此值是轉換的結果。
否則,轉換的結果是目標類型的未指定值。
這里的值既不是 NaN 也不是無窮大。 當向零舍入時,它們不在sbyte
的有效范圍內,即 -128 到 127,因此最后一個要點適用,這意味着此類轉換的結果未指定。
換句話說,此轉換的結果取決於您使用的編譯器。 不同的編譯器可以做不同的事情,它們仍將被稱為 C# 編譯器。 很可能您使用的任何編譯器都認為當要轉換的值離下限/上限很遠時,為轉換返回 0 是一個更好的主意。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.