Java的浮點數和整數的進制轉換


整數的表達
–原碼:第一位為符號位(0為正數,1為負數)
–反碼:符號位不動,原碼取反
–負數補碼:符號位不動,反碼加1
–正數補碼:和原碼相同
 
  -6      5
原碼 10000110 00000101
反碼 11111001 01111010
補碼 11111010 00000101

                                                      

補碼運輸的例子:

-6+5                                                         -4+5

  11111010                                                 11111100

+ 00000101                                            + 00000101

= 11111111                                              = 00000001

–打印整數的二進制表示
int a=-6; for(int i=0;i<32;i++){ int t=(a & (0x80000000)>>>i)>>>(31-i); System.out.print(t); }
 
Float的表示與定義 –支持 IEEE 754
• s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
• e全0 尾數附加位為0  否則尾數附加位為1, 附加位對應2^0
 •s*m*2^(e-127)
IEEE754 符號位  指數位 尾數位  指數偏移量 計算公式 附加位
float(單精度浮點數)  1[31] 8[23-30] 23[0-22] 127 s*m*2^(e-127) e全0 尾數附加位為0  否則為1, 附加位對應2^0
double(雙進度浮點數) 1[63] 11[52-62]  52[0-51]  1023 s*m*2^(e-1023) e全0 尾數附加位為0  否則為1, 附加位對應2^0

 

-5的IEEE 754表示.

11000000101000000000000000000000

-1*2^(129-127)*(2^0+2^-2) 紅色的部分對應附加位

一個IEEE754在線小工具: http://www.h-schmidt.net/FloatConverter/IEEE754.html

打印float的IEEE754表示的二進制串

public class FloatString { public static void main(String[] args){   float f = 100.2f;   int intString = Float.floatToIntBits(f);   if(intString!=0x7f800000||intString!=0xff800000||intString!=0x7fc00000)   {     for(int i =0;i<32;i++)     {       int t =( intString & (0x80000000>>>i) ) >>> (31-i);       System.out.print(t);     }   } } }

Java 的進制間轉換.

十進制轉成十六進制:Integer.toHexString(int i)   

十進制轉成八進制:Integer.toOctalString(int i) 

十進制轉成二進制:Integer.toBinaryString(int i)

十進制轉成別的進制的通用方法:Integer.toString(1, 8);

十六進制轉成十進制:Integer.valueOf("FFFF",16).toString()   

八進制轉成十進制:Integer.valueOf("876",8).toString() 

二進制轉十進制:Integer.valueOf("0101",2).toString()

轉成十進制的通用方法 Integer.parseInt(s, radix) /Integer.valueOf(s, radix)

 

Float 到double的轉換錯誤例子:

問題1:double類型轉float類型沒有出錯,float轉double類型出錯。
float f = 121.1f;
double d = f;
System.out.println(d);
輸出:
121.0999984741211

解決辦法1:
float f = 121.1f;
double d ;
BigDecimal bd = new BigDecimal(String.valueOf(f));
d = bd.doubleValue();
System.out.println(d);
輸出:
121.1

問題2:
double d = (3.3-2.1)/0.1;
System.out.println(d);
輸出:
11.999999999999996

解決辦法2:

BigDecimal b = new BigDecimal("3.3").subtract(new BigDecimal("2.1")).divide(new BigDecimal("0.1"));
System.out.println(b.doubleValue());

小數運算時,或可能會產生小數的運算時,都轉換成BigDecimal后再進行,得到結果后再轉換成相應類型。
如果感覺麻煩,可以寫一個基本運算的工具類,參考博客

說明:

java中整數默認是int,小數默認是double類型。(如要得到float類型,則加f如:12.1f)

int:4字節,long:8字節,float:4字節,double:8字節

float類型的變量只有7位的精度,而double類型的變量有15位的精度。

java在運算時會自動的提升變量的精度來進行運算。(double比float精度更高,所以可以自動的從float轉化至double再進行運算。)

BigDecimal介紹:

float和double只能用來做科學計算或者是工程計算,在商業計算中我們要用java.math.BigDecimal.

BigDecimal(double val)  Translates a double into a BigDecimal.這個方法會丟失精度.下面是該API中的說明.

Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances nonwithstanding.
The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one.

BigDecimal(String val) Translates the String repre sentation of a BigDecimal into a BigDecimal. 這個方法不會丟失精度.

做浮點數運算的工具類

import java.math.BigDecimal;
  
  /**
  
  * 由於Java的簡單類型不能夠精確的對浮點數進行運算,這個工具類提供精
  
  * 確的浮點數運算,包括加減乘除和四舍五入。
  
  */
  
  public class Arith{
  
  //默認除法運算精度
  
  private static final int DEF_DIV_SCALE = 10;
  
  //這個類不能實例化
  
  private Arith(){
  
  }
  
  /**
  
  * 提供精確的加法運算。
  
  * @param v1 被加數
  
  * @param v2 加數
  
  * @return 兩個參數的和
  
  */
  
  public static double add(double v1,double v2){
  
  BigDecimal b1 = new BigDecimal(Double.toString(v1));
  
  BigDecimal b2 = new BigDecimal(Double.toString(v2));
  
  return b1.add(b2).doubleValue();
  
  }
  
  /**
  
  * 提供精確的減法運算。
  
  * @param v1 被減數
  
  * @param v2 減數
  
  * @return 兩個參數的差
  
  */
  
  public static double sub(double v1,double v2){
  
  BigDecimal b1 = new BigDecimal(Double.toString(v1));
  
  BigDecimal b2 = new BigDecimal(Double.toString(v2));
  
  return b1.suBTract(b2).doubleValue();
  
  }
  
  /**
  
  * 提供精確的乘法運算。
  
  * @param v1 被乘數
  
  * @param v2 乘數
  
  * @return 兩個參數的積
  
  */
  
  public static double mul(double v1,double v2){
  
  BigDecimal b1 = new BigDecimal(Double.toString(v1));
  
  BigDecimal b2 = new BigDecimal(Double.toString(v2));
  
  return b1.multiply(b2).doubleValue();
  
  }
  
  /**
  
  * 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到
  
  * 小數點以后10位,以后的數字四舍五入。
  
  * @param v1 被除數
  
  * @param v2 除數
  
  * @return 兩個參數的商
  
  */
  
  public static double div(double v1,double v2){
  
  return div(v1,v2,DEF_DIV_SCALE);
  
  }
  
  /**
  
  * 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指
  
  * 定精度,以后的數字四舍五入。
  
  * @param v1 被除數
  
  * @param v2 除數
  
  * @param scale 表示表示需要精確到小數點以后幾位。
  
  * @return 兩個參數的商
  
  */
  
  public static double div(double v1,double v2,int scale){
  
  if(scale<0){
  
  throw new IllegalArgumentException(
  
  "The scale must be a positive integer or zero");
  
  }
  
  BigDecimal b1 = new BigDecimal(Double.toString(v1));
  
  BigDecimal b2 = new BigDecimal(Double.toString(v2));
  
  return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
  
  }
  
  /**
  
  * 提供精確的小數位四舍五入處理。
  
  * @param v 需要四舍五入的數字
  
  * @param scale 小數點后保留幾位
  
  * @return 四舍五入后的結果
  
  */
  
  public static double round(double v,int scale){
  
  if(scale<0){
  
  throw new IllegalArgumentException(
  
  "The scale must be a positive integer or zero");
  
  }
  
  BigDecimal b = new BigDecimal(Double.toString(v));
  
  BigDecimal one = new BigDecimal("1");
  
  return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
  
  }
  
  }; 

參考:http://blog.chinaunix.net/uid-26434689-id-3554399.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM