### 概述
Java的Float類主要的作用就是對基本類型float進行封裝,提供了一些處理float類型的方法,比如float到String類型的轉換方法或String類型到float類型的轉換方法,當然也包含與其他類型之間的轉換方法
> java float類型用IEEE754標準規定;
float占用4個字節,包括:
* 1bit(符號位):0表示正數,1表示負數;
* 8bits(指數位):float的偏移量為2^8 - 1,double的偏移量為2^11 - 1;
* 23bits(尾數位):實際尾數部分中的小數點后的數值,規約浮點數使用標準的二進制科學計數法表示,其尾數范圍在 \[1,2),非規約浮點數的尾數部分范圍在(0,1)

示例:
```
8.25 的 float 表示
整數8的二進制:1000
小數0.25的二進制:.01
8.25整體的二進制:1000.01 → 1.00001 * 2^3
小數點左移 3 位,所以指數部分(3 + 127) = 130,二進制是 10000010
尾數:去掉小數點前面的1,為 00001,補充到 23 位,000 0100 0000 0000 0000 0000
最終 8.25 在內存中存儲的二進制是:0100 0001 0000 0100 0000 0000 0000 0000
```
```
9.5 的 float 表示
9.5的二進制:1001.1 -> 1.0011 * 2^3
指數位是 (3 + 127)=130,二進制 10000010
尾數是 0011 000000 0000000000 000
最終 9.5 在內存中存儲的二進制是:010000010 0011 000000 0000000000 000,和程序打印出來的一致。
```
類繼承關系:
```
public final class Float extends Number implements Comparable<Float> {
public static final float POSITIVE_INFINITY = 1.0f / 0.0f; // 正無窮大
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f; // 負無窮大
public static final float NaN = 0.0f / 0.0f; // Not a Number(不是數)(輸出就是NaN)
// 指數部分的最大值(指數位的長度1個字節):127,最小值為-126
public static final int MAX_EXPONENT = 127;
public static final int MIN_EXPONENT = -126;
// 一個float占4個字節(32位)
public static final int SIZE = 32;
}
```
> 說明:這是java的規定,沒必要深究為什么1.0/0.0不報錯,不過1/0肯定報錯
#### 關于IEEE 754
> 在看Float前需要先了解IEEE 754標準,該標準定義了浮點數的格式還有一些特殊值,它規定了計算機中二進制與十進制浮點數轉換的格式及方法。規定了四種表示浮點數值的方法,單精確度(32位)、雙精確度(64位)、延伸單精確度(43位以上)與延伸雙精確度(79位以上)。多數編程語言支持單精確度和雙精確度,這里討論的Float就是Java的單精確度的實現
## 類方法:
1.toString\(float f\):
```
public String toString() {
return Float.toString(value);
}
public static String toString(float f) {
return FloatingDecimal.toJavaFormatString(f);
}
```
> FloatingDecimal:的作用是將float格式化轉換,即什么時候用數字顯示\(位數小于8位\),什么時候用指數顯示\(位數>=8位\)
> 更加詳細的在API中有說明
2.toHexString\(float f\):轉成16進制的字符串(用科學計數法表示)
```
public static String toHexString(float f) {
if (Math.abs(f) < FloatConsts.MIN_NORMAL
&& f != 0.0f ) {// float subnormal
// Adjust exponent to create subnormal double, then
// replace subnormal double exponent with subnormal float
// exponent
String s = Double.toHexString(Math.scalb((double)f,
/* -1022+126 */
DoubleConsts.MIN_EXPONENT-
FloatConsts.MIN_EXPONENT));
return s.replaceFirst("p-1022$", "p-126");
}
else // double string will be the same as float string
return Double.toHexString(f);
}
```
3.兩個valueOf\(\):將字符串/浮點數轉換成Float類型的對象
```
public static Float valueOf(String s) throws NumberFormatException {
return new Float(parseFloat(s));
}
public static Float valueOf(float f) {
return new Float(f);
}
```
4.parseFloat\(String s\):和valueOf重復了
```
public static float parseFloat(String s) throws NumberFormatException {
return FloatingDecimal.parseFloat(s);
}
```
5.isNaN\(float v\):判斷是不是一個‘不是數’\(NaN和任何東西都不想等,包括他自己\)
```
public static boolean isNaN(float v) {
return (v != v);
}
```
6.isInfinite\(float v\):判斷是不是正無窮或者負無窮(這兩個數使計算沒有任何意義)
```
public static boolean isInfinite(float v) {
return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}
```
7.floatToRawIntBits\(float value\) floatToIntBits\(float value\) intBitsToFloat\(int bits\):
> * 根據 IEEE 754 的浮點“單一形式”中的位布局,返回指定浮點值的表示形式
> * 根據 IEEE 754 的浮點“單一形式”中的位布局,返回指定浮點值的表示形式,并保留非數字 \(NaN\) 值。
> * 返回對應于給定的位表示形式的 float 值。該參數被認為是符合 IEEE 754 的浮點“單一形式”中的位布局規定的浮點值表示形式
```
public static native float intBitsToFloat(int bits);
public static native int floatToRawIntBits(float value);
public static int floatToIntBits(float value) {
int result = floatToRawIntBits(value);
// Check for NaN based on values of bit fields, maximum
// exponent and nonzero significand.
if ( ((result & FloatConsts.EXP_BIT_MASK) ==
FloatConsts.EXP_BIT_MASK) &&
(result & FloatConsts.SIGNIF_BIT_MASK) != 0)
result = 0x7fc00000;
return result;
}
```
8.compare\(float f1, float f2\):比較兩個float的大小
```
public static int compare(float f1, float f2) {
if (f1 < f2)
return -1; // Neither val is NaN, thisVal is smaller
if (f1 > f2)
return 1; // Neither val is NaN, thisVal is larger
// Cannot use floatToRawIntBits because of possibility of NaNs.
int thisBits = Float.floatToIntBits(f1);
int anotherBits = Float.floatToIntBits(f2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
```
### float二進制表示
```
int i = Float.floatToIntBits(8.25f);
System.out.println(Integer.toBinaryString(i)); // output==>1000001000001000000000000000000
```
### 精度損失
看下面的程序:
```
float f = 2.2f;
double d = (double) f;
System.out.println(f);
System.out.println(d);
```
打印出來的結果:
```
2.2
2.200000047683716
```
為什么會出現這種情況?
對于不能用二進制表示的 十進制小數,二進制小數位會進行循環,所以會損失精度。比如下面的語句會輸出 true:
```
System.out.println(2.2f == 2.20000001f);
```
### 測試
```
float num = 4.0f / 0.0f;
System.err.println(num); // java中規定分母不能為0,但是浮點數計算中不拋異常
output==>Infinity
```
- java演變
- JDK各個版本的新特性
- JDK1.5新特性
- JDK1.6新特性
- JDK1.7新特性
- JDK1.8新特性
- JAVA基礎
- 面向對象特性
- 多態
- 方法重載
- 方法重寫
- class
- 常量
- 訪問修飾符
- 類加載路徑
- java-equals
- 局部類
- java-hashCode
- Java類初始化順序
- java-clone方法
- JAVA對象實例化的方法
- 基礎部分
- JAVA基礎特性
- JAVA關鍵字
- javabean
- static
- 日期相關
- final
- interface
- 函數式接口
- JAVA異常
- 異常屏蔽
- try-with-resource資源泄露
- JAVA引用
- WeakReference
- SoftReference
- PhantomReference
- 位運算符
- try-with-resource語法糖
- JDK冷知識
- JAVA包裝類
- JAVA基本類型與包裝類
- java.lang.Boolean
- java.lang.Integer
- java.lang.Byte
- java.lang.Short
- java.lang.Long
- java.lang.Float
- java.lang.Double
- java.lang.Character
- 日期相關
- TemporalAdjusters
- String
- 字符串常量池
- String拼接
- String編譯期優化
- StringBuilder&StringBuffer
- intern
- 注解
- java標準注解
- 內置注解
- 元注解
- 自定義注解
- 注解處理器
- JVM注解
- Java8 Annotation新特性
- 反射-Reflective
- Reflection
- Class
- Constructor
- Method
- javabean-property
- MethodHandles
- 泛型
- 類型擦除
- bridge-method
- Accessor&Mutator方法
- enum
- JAVA數組
- finalize方法
- JAR文件
- JAVA高級編程
- CORBA
- JMX
- SPI
- Java SPI使用約定
- ServiceLoader
- 實際應用
- IO
- 工具類
- JDK常用工具類
- Objects
- System
- Optional
- Throwable
- Collections
- Array
- Arrays
- System
- Unsafe
- Number
- ClassLoader
- Runtime
- Object
- Comparator
- VarHandle
- 數據結構
- 棧-Stack
- 隊列(Queue)
- Deque
- PriorityQueue
- BlockingQueue
- SynchronousQueue
- ArrayBlockingQueue
- LinkedBlockingQueue
- PriorityBlockingQueue
- ConcurrentLinkedQueue
- 列表
- 迭代器
- KV鍵值對數據類型
- HashMap
- TreeMap
- Hash沖突
- ConcurrentHashMap
- JDK1.7 ConcurrentHashMap結構
- jdk7&jdk8區別
- 集合
- Vector
- Stack
- HashSet
- TreeSet
- ArrayList
- LinkedList
- ArrayList && LinkedList相互轉換
- 線程安全的集合類
- 集合類遍歷性能
- 并發容器
- CopyOnWriteArrayList
- ConcurrentHashMap
- 同步容器
- BitMap
- BloomFilter
- SkipList
- 設計模式
- 設計模式六大原則
- 單例模式
- 代理模式
- 靜態代理
- 動態代理
- JDK動態代理
- cglib動態代理
- spring aop
- 策略模式
- SpringAOP策略模式的運用
- 生產者消費者模式
- 迭代器模式
- 函數式編程
- 方法引用
- 性能問題
- Lambda
- Lambda類型檢查
- Stream
- findFirst和findAny
- reduce
- 原始類型流特化
- 無限流
- 收集器
- 并行流
- AOP
- 靜態織入
- aspect
- aspect的定義
- AspectJ與SpringAOP
- 動態織入
- 靜態代理
- 動態代理
- JDK動態代理
- CGLib動態代理
- Spring AOP
- SpringAOP五種通知類型
- @Before
- @AfterReturning
- @AfterThrowing
- @After
- @Around
- Aspect優先級
- SpringAOP切點表達式
- within
- execution
- 嵌套調用
- 系統優化與重構
- 重疊構造器模式
- 工具類構造器優化
- 常見面試題
- new Object()到底占用幾個字節
- 訪問修飾符
- cloneable接口實現原理
- 異常分類以及處理機制
- wait和sleep的區別
- 數組在內存中如何分配
- 類加載為什么要使用雙親委派模式,有沒有什么場景是打破了這個模式
- 類的實例化順序
- 附錄
- JAVA術語
- FAQ
- 墨菲定律
- 康威定律
- 軟件設計原則
- 阿姆達爾定律
- 字節碼工具
- OSGI