簡體   English   中英

為什么(int)(1.0 / x),其中x = 0會導致In32.MinValue而不是Int32.MaxValue?

[英]Why does (int)(1.0 / x) where x = 0 results in In32.MinValue rather than Int32.MaxValue?

在Java中

int x = 0;
(int)(-1.0 / x) -> Integer.MinValue
(int)(1.0 / x) -> Integer.MaxValue

但在C#中,

int x = 0;
(int)(-1.0 / x) -> Int32.MinValue
(int)(1.0 / x) -> Int32.MinValue!!

如果使用“unchecked”語句/運算符,行為將是相同的,如果使用“checked”,則它是溢出異常。

但可以肯定的是,在未經檢查的上下文中,除了1.0 / x(其中x = 0)之外,還會產生Int32.MaxValue,而不是Int32.MinValue。

我錯過了什么嗎?

真的,人們不應該期待任何事情。 從C#規范,第6.2.1節(強調我的):

對於從floatdouble到整數類型的轉換[...]。 - 在未經檢查的上下文中,轉換始終成功,並按如下方式進行。 - 如果操作數的值為NaN或無窮大,則轉換結果是目標類型的未指定值

將其與Java規范進行比較, 第5.1.3節

將浮點數轉換為整數類型T需要兩個步驟:

在第一步中,浮點數轉換為long(如果T為long)或轉換為int(如果T為byte,short,char或int),如下所示:

  • 如果浮點數是NaN(§4.2.3)[...],則轉換的第一步結果是int或long 0。
  • 否則,如果浮點數不是無窮大[...]
  • 否則,以下兩種情況之一必須為真:
    • 該值必須太小(大幅度或負無窮大的負值),第一步的結果是int或long類型的最小可表示值。
    • 該值必須太大(大幅度或正無窮大的正值),第一步的結果是int或long類型的最大可表示值。

基本上,這兩種語言有不同的保證,實現似乎都滿足這些保證。

我想, 由於規范較寬松,.NET JIT能夠使用更有效的轉換,這恰好會給int.MinValue帶來影響。

C#中的行為未定義。 引用C#語言規范 (和這個答案 ):

對於從float或double到整數類型的轉換,處理取決於發生轉換的溢出檢查上下文(第7.6.12節)。 在未選中的上下文中:如果操作數的值為NaN或無窮大,則轉換的結果是目標類型的未指定值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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