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

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

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

前言

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

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

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

例如:

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

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

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

但要特別注意:

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

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

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

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

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

先看這個(gè)例子:

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

long count = 10000000000L;
float value = count;

System.out.println(value);

這段代碼可以編譯。

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

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

2.1 long 的特點(diǎn)

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

-9.22e18 ~ 9.22e18

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

2.2 float 的特點(diǎn)

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

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

±3.4e38

雖然 float 只有 32 位,但因?yàn)樗褂弥笖?shù)位表示數(shù)量級(jí),所以能表示非常大的數(shù)值范圍。

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

可以這樣理解:

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

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

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

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

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

原類型可以自動(dòng)轉(zhuǎn)換到
byteshortint、long、float、double
shortint、long、float、double
charint、long、floatdouble
intlong、floatdouble
longfloat、double
floatdouble

注意幾點(diǎn):

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

下面是一個(gè)容易踩坑的例子:

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

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

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

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

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

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

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

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

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

2^24 等于:

16,777,216

看下面這個(gè)例子:

? 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。

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

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

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

五、double 是否就完全安全

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

因此:

不超過(guò) 2^53 的整數(shù),通常可以被 double 精確表示

例如:

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

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

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

但如果超過(guò) 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 都無(wú)損”的萬(wàn)能容器。

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

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

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

不要這樣寫:

? 錯(cuò)誤示例: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 精確計(jì)算

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

? 金額使用 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 時(shí)更推薦使用字符串,而不是直接傳入 double

6.3 混合運(yùn)算時(shí)留意結(jié)果類型

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

? long 與 float 混合運(yùn)算示例

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

float result = total * rate;

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

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

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

總結(jié)

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

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

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

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

相關(guān)文章

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

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

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

    druid連接泄露故障全面分析

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

    IDEA整合jeesite4.x及安裝教程

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

    全面解析Java中的HashMap類

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

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

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

    RestTemplate集成Ribbbon的示例代碼

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

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

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

    Java報(bào)錯(cuò)Non-terminating?decimal?expansion解決分析

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

    Spring實(shí)現(xiàn)國(guó)際化與本地化的詳細(xì)步驟

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

    java偽泛型知識(shí)點(diǎn)詳解

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

最新評(píng)論

宜良县| 澄城县| 无棣县| 江津市| 日喀则市| 阿尔山市| 同心县| 宜川县| 杭州市| 武夷山市| 普洱| 长汀县| 萨迦县| 孝义市| 临城县| 东辽县| 微山县| 广水市| 奇台县| 郯城县| 元阳县| 宁安市| 松潘县| 桃源县| 鄂伦春自治旗| 苍南县| 西畴县| 荆门市| 乐业县| 库伦旗| 洛浦县| 离岛区| 疏附县| 阜平县| 工布江达县| 冕宁县| 枣强县| 宁河县| 葵青区| 邹平县| 马边|