Hex2num.java
/*
* $Id: Hex2num.java,v 1.12 2008/02/25 08:35:52 koga Exp $
*
* Copyright (C) 2004 Koga Laboratory. All rights reserved.
*/
package org.mklab.tool.matrix;
import org.mklab.nfc.matrix.IntMatrix;
/**
* IEEE十六進表現から倍精度実数に変換するクラスです。
*
* <p>IEEE hexidecimal to double precision number conversion
*
* @author koga
* @version $Revision: 1.12 $
* @see org.mklab.tool.matrix.Hex2dec
*/
public class Hex2num {
/**
* メインメソッド
*
* @param args コマンドライン引数
*/
@SuppressWarnings("nls")
public static void main(String[] args) {
System.out.println("400921fb54442d18 = " + hex2num("400921fb54442d18"));
}
/**
* IEEE16進数表現(IEEE倍精度浮動小数点数)の文字列を実数に変換します。 16文字より少ない場合、ゼロで埋められます。
*
* @param s IEEE十六進表現
* @return number 倍精度実数
*/
public static double hex2num(String s) {
IntMatrix d = new IntMatrix(1, 16);
int n = s.length();
int z = '0';
int a = 'a';
d.setSubVector(IntMatrix.series(1, n), new IntMatrix(s.getBytes()).subtractElementWise(z));
IntMatrix idx = d.compareElementWise(".>", 10).find(); //$NON-NLS-1$
d.setSubVector(idx, d.getSubVector(idx).addElementWise(z + 10 - a));
boolean nf = d.getIntElement(1) > 7;
if (nf) {
d.setElement(1, d.getIntElement(1) - 8);
}
int e = 16 * (16 * (d.getIntElement(1) - 4) + d.getIntElement(2)) + d.getIntElement(3) + 1;
double f = 0;
for (int i = 16; i >= 4; i--) {
f = (f + d.getIntElement(i)) / 16;
}
double x;
if (e > 1023) {
if (f == 0.0) {
x = Double.POSITIVE_INFINITY;
} else {
x = Double.NaN;
}
} else if (e < -1022) {
x = f * Math.pow(2, -1022);
} else {
x = (1 + f) * Math.pow(2, e);
}
if (nf) {
x = -x;
}
return x;
}
}