Java中的double类型数据存储探析
一.double類型的存儲表示?
Java的浮點類型表示完全按照IEEE754標準(Standards of IEEE 754 floating point numbers),有興趣可以上IEEE標準網(wǎng)站(www.ieee.org)查閱.該標準的內(nèi)容基本上描述了浮點類型的存儲格式(Storage Layout),下面我從中總結(jié)幾段,來概括該標準,詳細信息請查閱標準原文.?
1.什么是浮點數(shù).?
????????計算機上表達實數(shù)有兩中方法:定點表示(fixed-point)和浮點表示(floating-point).
????????定點表示法就是在現(xiàn)有的數(shù)字中間的某個位置固定小數(shù)點,整數(shù)部分和小數(shù)部分的表示和一個普通整數(shù)的表示法沒什么兩樣.例如,我們的數(shù)字長度為4,小數(shù)點位于中間,那么你可以表示10.28,也可以表示00.01,與這種方法性質(zhì)類似的定點表示還有使用分數(shù)的形式.定點數(shù)的固定窗口形式使得他既不能夠表示非常大的數(shù)又不能表示非常小的數(shù).并且當除法發(fā)生時,大量 的精度丟失.?
浮點數(shù)采用科學計數(shù)法的形式來表示實數(shù).例如123.456可以表示成1.23456×102.相對于定點數(shù)的固定窗口(fixed Window)的限制,它采用的是浮動窗口(sliding window),因此可以表示較大精度范圍的一個實數(shù).?
2.存儲布局(Storage Layout)?
????????所謂的存儲布局就是一個浮點數(shù)在內(nèi)存中如何表示.我們知道浮點數(shù)有float和double,前者是4個字節(jié)也就是32位,后者是8個字節(jié)也就是64位.布局分別為:?
符號 指數(shù) 小數(shù)部分 偏移附加(bias)?
單精度 1[31] 8[30-23] 23[22-00] 127?
雙精度 1[63] 11[62-52] 52[51-00] 1023?
中括號內(nèi)為位的編號范圍,外面為該部分所占有的位的數(shù)量.偏移附加不屬于位表示的內(nèi)容,是一個常量,稍后解釋.?
符號? 只有一位:0-表示正數(shù) 1-表示負數(shù)?
指數(shù)部分:用指數(shù)部分的值(8位/11位,unsigned)的值 減去 偏移附加 得到該數(shù)實際的指數(shù) 例如值為200,實際指數(shù)為73=200-127.對于雙精度的double來說常量bias=1023?
尾數(shù):尾數(shù)是什么?對于一個科學計數(shù)法來講,形式象這樣的 L.M×BE,那么這個L.M就是所謂的尾數(shù)(mantisa).它由一個起始位和一個小數(shù)部分組成.舉個例子,5可以用科學計數(shù)法表示成不同形式:?
5*100?
0.5*101?
50*10-1?
那么我們引進一個概念,規(guī)范化形式(normalized form)和非規(guī)范化形式(denormalized form).我們定義規(guī)范化形式為小數(shù)點位于第一個不為0的數(shù)字后面的表達形式為規(guī)范化形式,因此上面的第一種形式為規(guī)范化形式,其他的為非規(guī)范化形式,Java中的浮點表示完全按照這個標準,只有兩種形式規(guī)范化形式:1.f 和 非規(guī)范化形式 0.f .?
二、BigDecimal對于浮點樹的處理
public BigDecimal(double val, MathContext mc) {if (Double.isInfinite(val) || Double.isNaN(val))throw new NumberFormatException("Infinite or NaN");// Translate the double into sign, exponent and significand, according// to the formulae in JLS, Section 20.10.22.long valBits = Double.doubleToLongBits(val);int sign = ((valBits >> 63) == 0 ? 1 : -1);int exponent = (int) ((valBits >> 52) & 0x7ffL);long significand = (exponent == 0? (valBits & ((1L << 52) - 1)) << 1: (valBits & ((1L << 52) - 1)) | (1L << 52));exponent -= 1075;// At this point, val == sign * significand * 2**exponent. 這就是那個公式//.....this.intVal = intVal;this.intCompact = compactVal; //最后轉(zhuǎn)化成定點型,因此做運算更準確些this.scale = scale;this.precision = prec;}總結(jié)
以上是生活随笔為你收集整理的Java中的double类型数据存储探析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 导入tsv文件_MySQL导
- 下一篇: 小程序VM3384 WAService.