簡體   English   中英

雙重到Int沒有損失精度

[英]Double to Int without lossy precision

以下聲明給出了編譯時錯誤“錯誤:(19,13)java:不兼容類型:可能從double轉換為int的有損轉換”

int i1 = 10.0;

// Error:(19, 14) java: incompatible types: possible lossy conversion from double to int

問題1

我理解錯誤,但編譯器可以不推斷 - 在這種特殊情況下 - 不會有精度損失?

問題2

如果我顯式地將double轉換為int然后它編譯很好(甚至不是警告),即使我在這個例子中肯定會失去精度

int i2 = (int)9999999999999.999999999;

如果我無法編譯第一種情況 - 沒有發生丟失 - 那么為什么第二個顯式轉換示例甚至不會生成編譯器警告?

理論上,編譯器可以推斷#1中的具體示例實際上不會根據文字的值松散精度,但正如您所見 - 它沒有。

顯式轉換信號通知編譯器您知道處理它的情況,因此代碼實際編譯。 但是,大多數IDE都可以配置為在這種情況下發出警告。

double值賦值給int變量需要縮小轉換 ,即使該值是編譯時常量,因此需要顯式轉換。

不同之處在於int (或shortchar )恆定值可以被分配給一個byteshort ,或char可變而不鑄造,如果常數實際上在各變量值范圍配合,以Java語言規范明確地記載,部分5.2。 作業上下文

賦值上下文允許將表達式的值賦值(第15.26節 )給變量; 必須將表達式的類型轉換為變量的類型。

賦值上下文允許使用以下之一:

  • 身份轉換( §5.1.1

  • 擴展的原始轉換(第5.1.2節

  • 擴大參考轉換(第5.1.5節

  • 一個拳擊轉換( §5.1.7 ),可選地后跟一個加寬的引用轉換

  • 一個拆箱轉換(第5.1.8節 ),可選地后跟一個加寬的基元轉換。

如果在應用上面列出的轉換后,結果類型是原始類型( §4.8 ),則可以應用未經檢查的轉換(第5.1.9節 )。

此外, 如果表達式是byteshortcharint類型的常量表達式(第15.28節

  • 如果變量的類型是byteshortchar ,則可以使用縮小的基元轉換,並且常量表達式的值可以在變量的類型中表示

  • 如果變量的類型是:則可以使用縮小的基元轉換,然后進行裝箱轉換:

    • Byte和常量表達式的值可在類型byte表示。

    • Short和常量表達式的值可以在short類型中表示。

    • Character和常量表達式的值可在char類型中表示。

回答問題1

根據編譯器的精度損失,因為編譯器只看到左邊有一個int變量,右邊有一個double值。 編譯器不是那么聰明,以至於在轉換為int時10.0不會失去精度。

理論上可以構建編譯器以允許編譯該語句,但這樣做沒有實際好處。 幾乎沒有人寫int x = 10.0

回答問題2

實際上,精度有所下降,但為什么編譯器不抱怨? 因為你使用了演員。 你寫了(int) 這是您向編譯器顯示您知道自己在做什么。 通過編寫演員表,你告訴它你知道可能會失去精確度。

有趣的問題

理論上這可能是有可能的, javac在做的時候不會抱怨:

short s = 12;

即使這里的12int類型的編譯時常量,也可以推斷出沒有精度丟失。 我想這是編譯器團隊認為最合適的。

好吧當你cast是一個不同的故事時,就像說“相信我,我知道我在做什么”,即使你精確度不高。

暫無
暫無

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

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