javajs.util.BC Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jmol Show documentation
Show all versions of jmol Show documentation
Jmol: an open-source Java viewer for chemical structures in 3D
package javajs.util;
/**
* byte converter
*
*
* @author Bob Hanson [email protected]
*
*/
public class BC {
public BC() {
// unnecessary to instantialize unless subclassed
}
public static float bytesToFloat(byte[] bytes, int j, boolean isBigEndian) throws Exception {
return intToFloat(bytesToInt(bytes, j, isBigEndian));
}
public static int bytesToShort(byte[] bytes, int j, boolean isBigEndian) {
int n = (isBigEndian ? (bytes[j + 1] & 0xff) | (bytes[j] & 0xff) << 8
: (bytes[j++] & 0xff) | (bytes[j++] & 0xff) << 8);
return (n > 0x7FFF ? n - 0x10000 : n);
}
public static int bytesToInt(byte[] bytes, int j, boolean isBigEndian) {
int n = (isBigEndian ? (bytes[j + 3] & 0xff) | (bytes[j + 2] & 0xff) << 8
| (bytes[j + 1] & 0xff) << 16 | (bytes[j] & 0xff) << 24
: (bytes[j++] & 0xff) | (bytes[j++] & 0xff) << 8
| (bytes[j++] & 0xff) << 16 | (bytes[j++] & 0xff) << 24);
/**
* @j2sNative
*
* return (n > 0x7FFFFFFF ? n - 0x100000000 : n);
*
*/
{
return n;
}
}
public static int intToSignedInt(int n) {
/**
* @j2sNative
*
* return (n > 0x7FFFFFFF ? n - 0x100000000 : n);
*
*/
{
return n;
}
}
public static float intToFloat(int x) throws Exception {
/**
* see http://en.wikipedia.org/wiki/Binary32
*
* [sign] [8 bits power] [23 bits fraction]
* 0x80000000 0x7F800000 0x7FFFFF
*
* (untested)
*
* @j2sNative
*
* if (x == 0) return 0;
* var o = javajs.util.BC;
* if (o.fracIEEE == null)
* o.setFracIEEE();
* var m = ((x & 0x7F800000) >> 23);
* return ((x & 0x80000000) == 0 ? 1 : -1) * o.shiftIEEE((x & 0x7FFFFF) | 0x800000, m - 149);
*
*/
{
return Float.intBitsToFloat(x);
}
}
/**
* see http://en.wikipedia.org/wiki/Binary64
*
* not concerning ourselves with very small or very large numbers and getting
* this exactly right. Just need a float here.
*
* @param bytes
* @param j
* @param isBigEndian
* @return float
*/
public static float bytesToDoubleToFloat(byte[] bytes, int j, boolean isBigEndian) {
{
// IEEE754: sign (1 bit), exponent (11 bits), fraction (52 bits).
// seeeeeee eeeeffff ffffffff ffffffff ffffffff xxxxxxxx xxxxxxxx xxxxxxxx
// b1 b2 b3 b4 b5 ---------float ignores----
if (fracIEEE == null)
setFracIEEE();
/**
* @j2sNative
* var o = javajs.util.BC;
* var b1, b2, b3, b4, b5;
*
* if (isBigEndian) {
* b1 = bytes[j] & 0xFF;
* b2 = bytes[j + 1] & 0xFF;
* b3 = bytes[j + 2] & 0xFF;
* b4 = bytes[j + 3] & 0xFF;
* b5 = bytes[j + 4] & 0xFF;
* } else {
* b1 = bytes[j + 7] & 0xFF;
* b2 = bytes[j + 6] & 0xFF;
* b3 = bytes[j + 5] & 0xFF;
* b4 = bytes[j + 4] & 0xFF;
* b5 = bytes[j + 3] & 0xFF;
* }
* var s = ((b1 & 0x80) == 0 ? 1 : -1);
* var e = (((b1 & 0x7F) << 4) | (b2 >> 4)) - 1026;
* b2 = (b2 & 0xF) | 0x10;
* return s * (o.shiftIEEE(b2, e) + o.shiftIEEE(b3, e - 8) + o.shiftIEEE(b4, e - 16)
* + o.shiftIEEE(b5, e - 24));
*/
{
double d;
if (isBigEndian)
d = Double.longBitsToDouble((((long) bytes[j]) & 0xff) << 56
| (((long) bytes[j + 1]) & 0xff) << 48
| (((long) bytes[j + 2]) & 0xff) << 40
| (((long) bytes[j + 3]) & 0xff) << 32
| (((long) bytes[j + 4]) & 0xff) << 24
| (((long) bytes[j + 5]) & 0xff) << 16
| (((long) bytes[j + 6]) & 0xff) << 8
| (((long) bytes[7]) & 0xff));
else
d = Double.longBitsToDouble((((long) bytes[j + 7]) & 0xff) << 56
| (((long) bytes[j + 6]) & 0xff) << 48
| (((long) bytes[j + 5]) & 0xff) << 40
| (((long) bytes[j + 4]) & 0xff) << 32
| (((long) bytes[j + 3]) & 0xff) << 24
| (((long) bytes[j + 2]) & 0xff) << 16
| (((long) bytes[j + 1]) & 0xff) << 8
| (((long) bytes[j]) & 0xff));
return (float) d;
}
}
}
private static float[] fracIEEE;
private static void setFracIEEE() {
fracIEEE = new float[270];
for (int i = 0; i < 270; i++)
fracIEEE[i] = (float) Math.pow(2, i - 141);
// System.out.println(fracIEEE[0] + " " + Parser.FLOAT_MIN_SAFE);
// System.out.println(fracIEEE[269] + " " + Float.MAX_VALUE);
}
/**
* only concerned about reasonable float values here -- private but not designated; called by JavaScript
*
* @param f
* @param i
* @return f * 2^i
*/
static double shiftIEEE(double f, int i) {
if (f == 0 || i < -140)
return 0;
if (i > 128)
return Float.MAX_VALUE;
return f * fracIEEE[i + 140];
}
// static {
// setFracIEEE();
// for (int i = -50; i < 50; i++) {
// float f = i * (float) (Math.random() * Math.pow(2, Math.random() * 100 - 50));
// int x = Float.floatToIntBits(f);
// int m = ((x & 0x7F800000) >> 23);
// float f1 = (float) (f == 0 ? 0 : ((x & 0x80000000) == 0 ? 1 : -1) * shiftIEEE((x & 0x7FFFFF) | 0x800000, m - 149));
// System.out.println(f + " " + f1);
// }
// System.out.println("binarydo");
// }
}