浮點數分為單精度和雙精度,Java中的單精度和雙精度分別為float和double.你們知道float和double是怎么存儲的嗎?

  float占4個字節,double占8個字節,為了方便起見,這里就只討論float類型.
  float其實和一個int型的大小是一樣的,一共32位,第一位表示符號,2-9表示指數,后面23位表示小數部分.這里不多說,請參考:http://blog.csdn.net/treeroot/archive/2004/09/05/95071.aspx

  這里只舉一個例子,希望能拋磚引玉,就是研究一下浮點數0.1的存儲形式,先運行這個程序.


?  public class Test{
  public static void main(String[] args) {
  int x = 0x3d800000;
  int i = 1 << 22;
  int j = 1 << 4;
  float f = 0.1f;
  int y = Float.floatToIntBits(f);
  float rest = f - ( (float) 1) / j;
  while (i > 0) {
  j <<= 1;
  float deta = ( (float) 1) / j;
  if (rest >= deta) {
  rest -= deta;
  x |= i;
  }
  i >>= 1;
  }
  pr(x);
  pr(y);
  }

  static void pr(int i) {
  System.out.println(Integer.toBinaryString(i));
  }

  }
?
  結果:
  111101110011001100110011001101
  111101110011001100110011001101

  程序說明:
  int x=0x3d80000;
  因為浮點表示形式為1.f*2n-127我們要表示0.1,可以知道n-127=-4,到n=123
  符號為正,可知前9是 001111011,暫時不考慮后面的23位小數,所以我們先假設x=0x3d800000;


?  int i = 1 << 22;
  i初始為第右起第23位為1,就是x的第10位


?  int j = 1 << 4;

  i初始為4,因為n-127為-4,這里是為了求它的倒數.


?  float f = 0.1f;
  int y = Float.floatToIntBits(f);

  y就是它的32位表示


?  float rest = f - ( (float) 1) / j;

  這個rest表示除了1.f中的1剩下的,也就是0.f


?  while (i > 0) {
  j <<= 1;
  float deta = ( (float) 1) / j;
  if (rest >= deta) {
  rest -= deta;
  x |= i;
  }
  i >>= 1;
  }

  這個循環來計算23位小數部分,如果rest不小于deta,表示這個位可以置為1.

  其他的不多說了,輸入結果是一樣的,可以說0.1這個浮點數肯定是不精確的,但是0.5可以精確的表示,想想為什么吧.