AndroidのOpenGL ESプログラミングしていて
ふとJavaの浮動小数点数 (Floating point numbers)のビット構造が気になったので、
脱線して適当にテストプログラムを作成してみた。
【ソース】
public class FloatingPoint3 {
float val = 0;
String bits; //
String sign; // 符号
String exponent; // 指数
String mantissa; // 仮数
private static int floatsize = 32; // floatのビットサイズ
public String getBitStr() {
return bits;
}
public float getVal() {
return val;
}
public void setVal(float val) {
this.val = val;
int bitval = Float.floatToRawIntBits(this.val);
// System.out.println("i >>>" + i);
StringBuffer sbf = new StringBuffer();
// String str = Integer.toBinaryString(bitval);
sbf.append(Integer.toBinaryString(bitval));
int addlen = floatsize - sbf.length();
for (int i = 0; i < addlen; i++) {
sbf.insert(0, '0');
}
bits = sbf.toString();
}
public String getSign() {
return bits.substring(0,1);
}
public String getExponent() {
return bits.substring(1,9);
}
public String getMantissa() {
return bits.substring(9,32);
}
// 指数の値取得
public int getExponentVal() {
int exponent_maxsize = 8;
String src = getExponent();
int r = 0;
for(int i=0;i<src.length();i++){
if(src.charAt(i) == '1'){
r += 0x01 << ((exponent_maxsize-1) - i);
}
}
r = r - 127; // 指数部 は、0111 1111=127 で 0乗なので
return r;
}
}
package com.naozary.test.FloatingPoint;
import java.util.Formatter;
public class FloatingPoint4 {
float val = 0;
int bits; //
public int getBit() {
return bits;
}
public float getVal() {
return val;
}
public void setVal(float val) {
this.val = val;
bits = Float.floatToRawIntBits(this.val);
}
// 符号
public int getSign() {
return (bits >> 31) & 0x01;
}
// 指数
public int getExponent() {
return (bits >> 23) & 0xff;
}
// 仮数
public int getMantissa() {
return bits & 0x7fffff;
}
// 指数の値取得
public int getExponentVal() {
return getExponent() - 127; // 指数部 は、0111 1111=127 で 0乗なので
}
public String toString() {
StringBuffer sbf = new StringBuffer();
sbf.append(getFormatStr("%f = 0x%08X \n",val,bits));
sbf.append(getFormatStr("符号 : %d \n",getSign()));
sbf.append(getFormatStr("指数 : 0x%02X (=%d) \n",getExponent(),getExponentVal()));
sbf.append(getFormatStr("仮数 : 0x%06X \n",getMantissa()));
return sbf.toString();
}
// 固定小数点数(上位2バイト:整数部分 下位2バイト:少数部分)
public int getFixedPointNumber() {
int n = 0;
n = 0x800000 | getMantissa(); // ヒドンビットを付加
int e = 7; // 指数が0でも左に7シフトさせなければならない
e = e - getExponentVal();
n = n >> e; // 少数点位置を合わせる
n = getSign() == 1 ? -n : n; // 符号を考慮
return n;
}
public String getFormatStr(String arg0,Object... args) {
StringBuilder builder = new StringBuilder();
Formatter formatter = new Formatter(builder);
formatter.format(arg0,args);
return formatter.out().toString();
}
}
package com.naozary.test.FloatingPoint;
・
・
省略
・
・
public class TestFloat extends JApplet implements ActionListener {
・
・
省略
・
・
public void case001() {
printf("********** %s() ********** \n",Thread.currentThread().getStackTrace()[1].getMethodName());
FloatingPoint3 fp = new FloatingPoint3();
fp.setVal(10.75F);
disp(fp);
fp.setVal(-10.75F);
disp(fp);
fp.setVal(0.33333F);
disp(fp);
fp.setVal(0.66666F);
disp(fp);
fp.setVal(0.0F);
disp(fp);
fp.setVal(1F);
disp(fp);
fp.setVal(2F);
disp(fp);
fp.setVal(3F);
disp(fp);
fp.setVal(4F);
disp(fp);
fp.setVal(5.5F);
disp(fp);
fp.setVal(0.55F);
disp(fp);
}
public void case002() {
printf("********** %s() ********** \n",Thread.currentThread().getStackTrace()[1].getMethodName());
FloatingPoint4 fp = new FloatingPoint4();
fp.setVal(10.75F);
printf(fp.toString());
printf("\n");
fp.setVal(-10.75F);
printf(fp.toString());
printf("\n");
fp.setVal(0.33333F);
printf(fp.toString());
printf("\n");
fp.setVal(0.66666F);
printf(fp.toString());
printf("\n");
fp.setVal(0.0F);
printf(fp.toString());
printf("\n");
fp.setVal(1F);
printf(fp.toString());
printf("\n");
fp.setVal(2F);
printf(fp.toString());
printf("\n");
fp.setVal(5.5F);
printf(fp.toString());
printf("\n");
fp.setVal(0.55F);
printf(fp.toString());
printf("\n");
}
public void case003() {
printf("********** %s() ********** \n",Thread.currentThread().getStackTrace()[1].getMethodName());
FloatingPoint4 fp = new FloatingPoint4();
fp.setVal(1F);
printf(fp.toString());
printf("固定少数点数:0x%08X \n",fp.getFixedPointNumber());
// printf("固定少数点数:0x%08X \n",-fp.getFixedPointNumber());
printf("\n");
fp.setVal(-1F);
printf(fp.toString());
printf("固定少数点数:0x%08X \n",fp.getFixedPointNumber());
printf("\n");
fp.setVal(5.5F);
printf(fp.toString());
printf("固定少数点数:0x%08X \n",fp.getFixedPointNumber());
printf("\n");
fp.setVal(-5.5F);
printf(fp.toString());
printf("固定少数点数:0x%08X \n",fp.getFixedPointNumber());
printf("\n");
fp.setVal(0.33333F);
printf(fp.toString());
printf("固定少数点数:0x%08X \n",fp.getFixedPointNumber());
printf("\n");
fp.setVal(0.66666666F);
printf(fp.toString());
printf("固定少数点数:0x%08X \n",fp.getFixedPointNumber());
printf("\n");
}
public void disp(FloatingPoint3 fp) {
printf("%f = %s \n",fp.getVal(),fp.getBitStr());
printf("符号 : %s \n", fp.getSign());
printf("指数 : %s (=%d)\n", fp.getExponent(),fp.getExponentVal());
printf("仮数 : %s \n", fp.getMantissa());
// printf("fp.getExponentVal() >>>%d \n", fp.getExponentVal());
printf("\n");
}
public static void main(String[] args) {
TestFloat t01 = new TestFloat();
t01.case001();
t01.case002();
t01.case003();
}
}
【実行結果】
0 件のコメント:
コメントを投稿