最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java寬化基本類型轉(zhuǎn)換與精度丟失詳解(為什么long可以自動轉(zhuǎn)float)

 更新時間:2026年05月21日 08:27:01   作者:超級苦力怕  
java中l(wèi)ong到float的轉(zhuǎn)換屬于自動類型轉(zhuǎn)換,因為float的范圍比long更大,這篇文章主要介紹了Java寬化基本類型轉(zhuǎn)換與精度丟失的相關(guān)資料,詳細介紹了為什么long可以自動轉(zhuǎn)float,需要的朋友可以參考下

前言

很多同學(xué)第一次看到 long 可以自動賦值給 float 時,會覺得很反直覺:long 是 64 位整數(shù),float 是 32 位浮點數(shù),為什么 64 位能自動轉(zhuǎn) 32 位?關(guān)鍵在于 Java 判斷“寬化轉(zhuǎn)換”時,看重的是數(shù)值表示范圍,而不是簡單的內(nèi)存位數(shù)。本文會從寬化基本類型轉(zhuǎn)換、long -> float 的原因、精度丟失和工程避坑四個角度講清楚這個問題。

一、先給結(jié)論:寬化不等于精度無損

Java 中存在一種自動轉(zhuǎn)換,叫寬化基本類型轉(zhuǎn)換(Widening Primitive Conversion)。

例如:

? 寬化基本類型轉(zhuǎn)換示例

int a = 10;
long b = a;
float c = b;
double d = c;

這些代碼都可以通過編譯,因為 Java 允許某些基本類型自動轉(zhuǎn)換到另一些表示范圍更大的類型。

但要特別注意:

寬化轉(zhuǎn)換 = 編譯器允許自動轉(zhuǎn)換
寬化轉(zhuǎn)換 ≠ 結(jié)果一定完全精確

尤其是整數(shù)轉(zhuǎn)浮點數(shù)時,可能出現(xiàn)精度丟失。

轉(zhuǎn)換是否自動是否一定精確說明
int -> longlong 可以精確容納所有 int
int -> doubledouble 有足夠精度表示所有 int
long -> floatfloat 范圍夠大,但精度不夠
long -> double不一定大于 2^53long 可能丟精度
float -> double通常保留已有 float 值但不能恢復(fù) float 已經(jīng)丟失的信息

?? 核心結(jié)論: Java 的“寬化”主要強調(diào)可表示范圍擴大,不保證所有轉(zhuǎn)換都精度無損。

二、為什么 64 位 long 可以轉(zhuǎn) 32 位 float

先看這個例子:

? long 自動轉(zhuǎn) float 示例

long count = 10000000000L;
float value = count;

System.out.println(value);

這段代碼可以編譯。

很多人會困惑:long 是 64 位,float 是 32 位,為什么不需要強制轉(zhuǎn)換?

原因是:longfloat 的“位數(shù)”不能直接比較。

2.1 long 的特點

long 是 64 位整數(shù),取值范圍大約是:

-9.22e18 ~ 9.22e18

它適合保存大整數(shù)、時間戳、計數(shù)器、分布式 ID 等。

2.2 float 的特點

float 是 32 位浮點數(shù),采用類似科學(xué)計數(shù)法的結(jié)構(gòu)。

它的最大表示范圍大約是:

±3.4e38

雖然 float 只有 32 位,但因為它使用指數(shù)位表示數(shù)量級,所以能表示非常大的數(shù)值范圍。

2.3 關(guān)鍵區(qū)別:范圍和精度不是一回事

可以這樣理解:

類型更擅長什么短板
long精確表示整數(shù)范圍沒有 float 的指數(shù)范圍大
float表示很大或很小的數(shù)量級有效精度有限

因此,long -> float 在 Java 中被認為是寬化轉(zhuǎn)換:float 的數(shù)值范圍能覆蓋 long 的范圍。

但這不代表 float 能精確保存每一個 long。

三、寬化基本類型轉(zhuǎn)換有哪些

常見寬化基本類型轉(zhuǎn)換可以先記住下面這張表:

原類型可以自動轉(zhuǎn)換到
byteshort、int、long、floatdouble
shortint、long、floatdouble
charint、longfloat、double
intlong、floatdouble
longfloat、double
floatdouble

注意幾點:

  • boolean 不參與數(shù)值類型轉(zhuǎn)換。
  • char 可以轉(zhuǎn) int,但不能自動轉(zhuǎn) short。
  • byte 不能自動轉(zhuǎn) char。
  • 整數(shù)轉(zhuǎn)浮點數(shù)時,可能出現(xiàn)精度變化。

下面是一個容易踩坑的例子:

? char 自動轉(zhuǎn) int 示例

char c = 'A';
int code = c;

System.out.println(code); // 65

這里 char 轉(zhuǎn)成 int 后,得到的是字符對應(yīng)的 Unicode 編碼值。

?? 誤區(qū):只要位數(shù)小,就一定能自動轉(zhuǎn)到位數(shù)大的類型

正確理解: Java 的寬化轉(zhuǎn)換有明確規(guī)則,不是單純比較位數(shù)。例如 char 是 16 位,但不能自動轉(zhuǎn)成同樣 16 位的 short

四、精度丟失是怎么發(fā)生的

float 的有效精度大約只有 6 到 7 位十進制有效數(shù)字。

從二進制角度看,float 的尾數(shù)有效精度大約是 24 位。因此,當(dāng)整數(shù)超過 2^24 后,float 就不一定能精確表示每一個整數(shù)。

2^24 等于:

16,777,216

看下面這個例子:

? long 轉(zhuǎn) float 丟失精度示例

long original = 16777217L; // 2^24 + 1
float converted = original;
long back = (long) converted;

System.out.println(original); // 16777217
System.out.println(back);     // 16777216
System.out.println(original - back); // 1

這里 167772172^24 多 1。

它可以放進 float 的表示范圍里,但 float 沒有足夠的有效位精確保存這個低位的 1,所以轉(zhuǎn)換后再轉(zhuǎn)回 long,數(shù)值發(fā)生了變化。

能放下,不代表能一模一樣地放下。

這就是 long -> float 最容易誤解的地方。

五、double 是否就完全安全

double 的有效精度比 float 高得多,大約有 53 位二進制有效精度。

因此:

不超過 2^53 的整數(shù),通??梢员?double 精確表示

例如:

? double 可精確表示較大整數(shù)示例

long id = 9007199254740992L; // 2^53
double value = id;
long back = (long) value;

System.out.println(id == back); // true

但如果超過 2^53,double 也可能丟失整數(shù)精度。

? double 也可能丟失 long 精度示例

long id = 9007199254740993L; // 2^53 + 1
double value = id;
long back = (long) value;

System.out.println(id);   // 9007199254740993
System.out.println(back); // 9007199254740992

所以,doublefloat 更適合保存較大范圍和較高精度的小數(shù),但它也不是“所有 long 都無損”的萬能容器。

六、工程中應(yīng)該怎么避坑

6.1 不要把 ID 轉(zhuǎn)成 float

像訂單號、用戶 ID、Snowflake ID、數(shù)據(jù)庫主鍵這類數(shù)據(jù),本質(zhì)上需要精確保存。

不要這樣寫:

? 錯誤示例:ID 轉(zhuǎn) float

long userId = 16777217L;
float value = userId; // 可能丟失精度

更合理的做法是保持 long,或者在展示層轉(zhuǎn)成字符串。

? ID 使用字符串展示示例

long userId = 16777217L;
String text = String.valueOf(userId);

6.2 金額不要依賴 float 或 double 精確計算

金額計算要求精確,不能依賴二進制浮點數(shù)做最終計算。

? 金額使用 BigDecimal 示例

import java.math.BigDecimal;

BigDecimal price = new BigDecimal("0.1");
BigDecimal count = new BigDecimal("3");

BigDecimal total = price.multiply(count);
System.out.println(total); // 0.3

注意:創(chuàng)建 BigDecimal 時更推薦使用字符串,而不是直接傳入 double

6.3 混合運算時留意結(jié)果類型

如果 longfloat 一起運算,結(jié)果可能變成 float

? long 與 float 混合運算示例

long total = 16777217L;
float rate = 1.0F;

float result = total * rate;

這段代碼能編譯,但 result 已經(jīng)是 float,可能失去整數(shù)精度。

?? 誤區(qū):自動轉(zhuǎn)換就代表安全轉(zhuǎn)換

正確理解: 自動轉(zhuǎn)換只代表編譯器允許。是否符合業(yè)務(wù)語義,還要看數(shù)據(jù)是否需要精確保存。

總結(jié)

問題結(jié)論
為什么 long 可以自動轉(zhuǎn) float因為 float 的數(shù)值表示范圍覆蓋 long
為什么還會丟精度float 有效精度有限,不能精確表示所有大整數(shù)
寬化看的是位數(shù)嗎不是單純看位數(shù),而是 Java 規(guī)定的類型轉(zhuǎn)換規(guī)則和表示范圍
double 是否完全安全不是,超過 2^53 的整數(shù)也可能丟失精度
工程中怎么處理 ID保持 long 或轉(zhuǎn)字符串,不要轉(zhuǎn) float
工程中怎么處理金額使用 BigDecimal,不要依賴 floatdouble 精確計算

這篇文章可以壓縮成一句話:寬化轉(zhuǎn)換解決的是“能不能自動轉(zhuǎn)”,不是“能不能精確還原”。

?? 核心結(jié)論: long -> float 合法,是因為 float 的表示范圍足夠大;但 float 精度有限,不能保存所有 long 的細節(jié)。寫業(yè)務(wù)代碼時,凡是 ID、金額、精確計數(shù),都不要隨意轉(zhuǎn)成浮點數(shù)。

到此這篇關(guān)于Java寬化基本類型轉(zhuǎn)換與精度丟失的文章就介紹到這了,更多相關(guān)Java long可以自動轉(zhuǎn)float內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java正則驗證正整數(shù)的方法分析【測試可用】

    Java正則驗證正整數(shù)的方法分析【測試可用】

    這篇文章主要介紹了Java正則驗證正整數(shù)的方法,結(jié)合實例形式對比分析了java針對正整數(shù)的驗證方法及相關(guān)注意事項,需要的朋友可以參考下
    2017-08-08
  • druid連接泄露故障全面分析

    druid連接泄露故障全面分析

    這篇文章主要介紹了druid連接泄露故障全面分析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • IDEA整合jeesite4.x及安裝教程

    IDEA整合jeesite4.x及安裝教程

    本文給大家介紹IDEA整合jeesite4.x及安裝教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-07-07
  • 全面解析Java中的HashMap類

    全面解析Java中的HashMap類

    HashMap類為Java提供了鍵值對應(yīng)的map類型,本文將從源碼角度全面解析Java中的HashMap類,同時包括其各種常用操作方法等,歡迎參考與借鑒
    2016-05-05
  • springboot創(chuàng)建攔截器過程圖解

    springboot創(chuàng)建攔截器過程圖解

    這篇文章主要介紹了springboot創(chuàng)建攔截器過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • RestTemplate集成Ribbbon的示例代碼

    RestTemplate集成Ribbbon的示例代碼

    這篇文章主要介紹了RestTemplate集成Ribbbon的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • 使用Java反射模擬實現(xiàn)Spring的IoC容器的操作

    使用Java反射模擬實現(xiàn)Spring的IoC容器的操作

    這篇文章主要介紹了使用Java反射模擬實現(xiàn)Spring的IoC容器的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java報錯Non-terminating?decimal?expansion解決分析

    Java報錯Non-terminating?decimal?expansion解決分析

    這篇文章主要為大家介紹了Java報錯Non-terminating?decimal?expansion解決方案及原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • Spring實現(xiàn)國際化與本地化的詳細步驟

    Spring實現(xiàn)國際化與本地化的詳細步驟

    在全球化背景下,應(yīng)用支持多語言和本地化顯示是滿足不同地區(qū)用戶需求的關(guān)鍵,Spring 的國際化與本地化功能,能幫助開發(fā)者輕松實現(xiàn)應(yīng)用的語言切換與區(qū)域適配,下面從核心概念、實現(xiàn)步驟、應(yīng)用場景等方面詳細解析其實現(xiàn)方式,需要的朋友可以參考下
    2025-06-06
  • java偽泛型知識點詳解

    java偽泛型知識點詳解

    在本篇文章里小編給大家整理的是一篇關(guān)于java偽泛型知識點詳解內(nèi)容,有需要的朋友們可以跟著學(xué)習(xí)參考下。
    2021-06-06

最新評論

德保县| 开原市| 琼中| 盘锦市| 富源县| 江油市| 始兴县| 常山县| 南投县| 西乡县| 高淳县| 阿拉尔市| 遂川县| 新宾| 汕尾市| 隆化县| 富顺县| 东明县| 临武县| 油尖旺区| 普宁市| 白朗县| 集贤县| 望城县| 河曲县| 阳西县| 靖西县| 昂仁县| 湄潭县| 麻城市| 茌平县| 上高县| 乌海市| 麟游县| 海阳市| 乐安县| 苗栗县| 鄂州市| 阿图什市| 怀安县| 蓬安县|