簡體   English   中英

將Long.MAX_VALUE轉換為Float

[英]Convert Long.MAX_VALUE to Float

通過將Integer轉換為Float,Float轉換為Long,Long轉換為Int,我很開心,然后我對下面的這種行為感到困惑。

當我將一個字符串轉換s代表Long.MAX_VALUE (63個1S)我得到了一個NumberFormatException ,其預期。 因為Long是64位而Integer是32位所以有額外的31 1。 (這是我的猜測也許是另一個原因請糾正我,如果我錯了)

但是我不確定為什么在將Long轉換為Float時沒有得到NumberFormatException Long為64位, Float為32位,就像Integer一樣。 我知道位被不同地解釋為Float (IEEE 754浮點“單格式”位布局)但是所有其他額外的31位發生了什么? 我真的迷失在這里......

另外如何得到9.223372E18這是1011111000000000000000000000000位字符串? 那些0來自哪里?

public static void main(String[] args){
    String s = String.valueOf(Long.MAX_VALUE); 
    print(s); //prints 9223372036854775807
    print(Long.toBinaryString(Long.MAX_VALUE)); //prints 111111111111111111111111111111111111111111111111111111111111111
    //Integer.valueOf(s) this throws NumberFormatException because Long is 64 bits and Integer is 32 so s is too large to be an Integer
    print(Float.valueOf(s)); //prints 9.223372E18 Why no NumberFormatException? and how did it result 9.223372E18?

    float f = Float.valueOf(s);
    int intBits = Float.floatToIntBits(f); 
    print(Integer.toBinaryString(intBits)); //1011111000000000000000000000000 How come? s was a String of 1s now there are 0s?
}

public static <T> void print(T arg){
    System.out.println(arg);
} 

首先,讓我們確認轉換是正確的。

Long.MAX_VALUE是9223372036854775807(19位數)。 如您所見,該值大約是您打印的值: 9.223372E18

long的精度始終為1 但是, float的精度取決於數字的大小。

在一個IEEE單精度浮點數 ,其float是,有在尾數只有24位精度,或存儲的“分數”的一部分。 因此float表示的實際值是Long.MAX_VALUE的實際值的Long.MAX_VALUE

Float.floatToIntBits

正如您Float.floatToIntBitsFloat.floatToIntBits方法產生的位數與原始long位表示不同。

根據IEEE 754浮點“單一格式”位布局返回指定浮點值的表示形式。 位31(由掩碼0x80000000選擇的位)表示浮點數的符號。 位30-23(由掩碼0x7f800000選擇的位)表示指數。 比特22-0(由掩碼0x007fffff選擇的比特)表示浮點數的有效數(有時稱為尾數)。

(剪斷)

返回 :表示浮點數的位。

此方法不會將轉換為int ,它只提供碰巧存儲在int中的float的位表示。 int表示的值預計不會float相同。

轉換

那些零是浮點數的尾數。 longfloat的實際轉換包括找到最高位的符號,找到建立指數的值的大小,並將值的其余部分轉換為尾數。

因為一個的精度float在規模Long.MAX_VALUE被限制,一些精度損失。 最終結果是float值略微向上舍入。 因為Long.MAX_VALUE是2的冪的1,所以向上舍入產生2的冪,其在尾數中顯示為全零。

您可以使用Math.ulp (最后一個單位)以數字的比例查看浮點值的精度。

Math.ulp(f)

產量

1.09951163E12

如您所見,對於Long.MAX_VALUEfloat ,差異非常大。 (相應的double的ulp是2048.0 。大,但是比float的ulp要小得多。)但是它符合預期值幾乎為10 19 - float約為7位精度。

關於print(Float.valueOf(s)); //prints 9.223372E18 Why no NumberFormatException? and how did it result 9.223372E18? print(Float.valueOf(s)); //prints 9.223372E18 Why no NumberFormatException? and how did it result 9.223372E18?

浮標的表示方式不同。 根據Java語言規范 ,有問題的數字在Float的范圍內。

JavaDoc中描述了精確轉換,包括舍入

關於`print(Integer.toBinaryString(intBits)); // 1011111000000000000000000000000怎么來的? s是1s的字符串現在有0?':

Float.floatToIntBits(f)不返回“與整數相同的數字”。 它的語義在JavaDoc中描述

float表示在四個字節(32位)上, long表示在8個字節(64位)上。 long轉換為float ,會丟失一半的數據,因為不能將64位轉換為32位。 這就是你丟失很多比特的原因。

float使用23位尾數,因此大於2 ^ 23的整數將被截斷。

這就是為什么你能夠施放和施放具有它的結果的原因。

暫無
暫無

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

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