5722efd084c00327f784332fb58d4be585892b91
[jalview.git] / src2 / javajs / util / BC.java
1 package javajs.util;
2
3 /**
4  * byte converter
5  * 
6  * 
7  * @author Bob Hanson hansonr@stolaf.edu
8  * 
9  */
10 public class BC {
11
12   public BC() {
13     // unnecessary to instantialize unless subclassed
14   }
15   
16   public static float bytesToFloat(byte[] bytes, int j, boolean isBigEndian) throws Exception {
17     return intToFloat(bytesToInt(bytes, j, isBigEndian));
18   }
19
20   public static int bytesToShort(byte[] bytes, int j, boolean isBigEndian) {
21     int n = (isBigEndian ? (bytes[j + 1] & 0xff) | (bytes[j] & 0xff) << 8
22         : (bytes[j++] & 0xff) | (bytes[j++] & 0xff) << 8);
23       return (n > 0x7FFF ? n - 0x10000 : n);
24   }
25
26   public static int bytesToInt(byte[] bytes, int j, boolean isBigEndian) {
27     int n = (isBigEndian ? (bytes[j + 3] & 0xff) | (bytes[j + 2] & 0xff) << 8
28         | (bytes[j + 1] & 0xff) << 16 | (bytes[j] & 0xff) << 24
29         : (bytes[j++] & 0xff) | (bytes[j++] & 0xff) << 8
30             | (bytes[j++] & 0xff) << 16 | (bytes[j++] & 0xff) << 24);
31     /**
32      * @j2sNative
33      * 
34      * return (n > 0x7FFFFFFF ? n - 0x100000000 : n);
35      *   
36      */
37     {
38       return n;
39     }
40   }
41
42   public static int intToSignedInt(int n) {
43     /**
44      * @j2sNative
45      * 
46      * return (n > 0x7FFFFFFF ? n - 0x100000000 : n);
47      *   
48      */
49     {
50       return n;
51     }    
52   }
53   public static float intToFloat(int x) throws Exception {
54     /**
55      * see http://en.wikipedia.org/wiki/Binary32
56      * 
57      * [sign]      [8 bits power] [23 bits fraction]
58      * 0x80000000  0x7F800000      0x7FFFFF
59      * 
60      * (untested)
61      * 
62      * @j2sNative
63      * 
64      *       if (x == 0) return 0;
65      *       var o = javajs.util.BC;
66      *       if (o.fracIEEE == null)
67      *         o.setFracIEEE();
68      *       var m = ((x & 0x7F800000) >> 23);
69      *       return ((x & 0x80000000) == 0 ? 1 : -1) * o.shiftIEEE$D$I((x & 0x7FFFFF) | 0x800000, m - 149);
70      *  
71      */
72     {
73     return Float.intBitsToFloat(x);
74     }
75   }
76
77   /**
78    * see http://en.wikipedia.org/wiki/Binary64
79    *  
80    * not concerning ourselves with very small or very large numbers and getting
81    * this exactly right. Just need a float here.
82    * 
83    * @param bytes
84    * @param j
85    * @param isBigEndian
86    * @return float
87    */
88   public static float bytesToDoubleToFloat(byte[] bytes, int j, boolean isBigEndian) {
89     {
90       // IEEE754: sign (1 bit), exponent (11 bits), fraction (52 bits).
91       // seeeeeee eeeeffff ffffffff ffffffff ffffffff xxxxxxxx xxxxxxxx xxxxxxxx
92       //     b1      b2       b3       b4       b5    ---------float ignores----
93
94         if (fracIEEE == null)
95            setFracIEEE();
96         
97       /**
98        * @j2sNative
99        *       var b1, b2, b3, b4, b5;
100        *       
101        *       if (isBigEndian) {
102        *       b1 = bytes[j] & 0xFF;
103        *       b2 = bytes[j + 1] & 0xFF;
104        *       b3 = bytes[j + 2] & 0xFF;
105        *       b4 = bytes[j + 3] & 0xFF;
106        *       b5 = bytes[j + 4] & 0xFF;
107        *       } else {
108        *       b1 = bytes[j + 7] & 0xFF;
109        *       b2 = bytes[j + 6] & 0xFF;
110        *       b3 = bytes[j + 5] & 0xFF;
111        *       b4 = bytes[j + 4] & 0xFF;
112        *       b5 = bytes[j + 3] & 0xFF;
113        *       }
114        *       var s = ((b1 & 0x80) == 0 ? 1 : -1);
115        *       var e = (((b1 & 0x7F) << 4) | (b2 >> 4)) - 1026;
116        *       b2 = (b2 & 0xF) | 0x10;
117        *       return s * (C$.shiftIEEE$D$I(b2, e) +C$.shiftIEEE$D$I(b3, e - 8) + C$.shiftIEEE$D$I(b4, e - 16)
118        *         + C$.shiftIEEE$D$I(b5, e - 24));
119        */
120       {
121         double d;
122         
123         if (isBigEndian)
124           d = Double.longBitsToDouble((((long) bytes[j]) & 0xff) << 56
125              | (((long) bytes[j + 1]) & 0xff) << 48
126              | (((long) bytes[j + 2]) & 0xff) << 40
127              | (((long) bytes[j + 3]) & 0xff) << 32
128              | (((long) bytes[j + 4]) & 0xff) << 24
129              | (((long) bytes[j + 5]) & 0xff) << 16
130              | (((long) bytes[j + 6]) & 0xff) << 8 
131              | (((long) bytes[7]) & 0xff));
132         else
133           d = Double.longBitsToDouble((((long) bytes[j + 7]) & 0xff) << 56
134              | (((long) bytes[j + 6]) & 0xff) << 48
135              | (((long) bytes[j + 5]) & 0xff) << 40
136              | (((long) bytes[j + 4]) & 0xff) << 32
137              | (((long) bytes[j + 3]) & 0xff) << 24
138              | (((long) bytes[j + 2]) & 0xff) << 16
139              | (((long) bytes[j + 1]) & 0xff) << 8 
140              | (((long) bytes[j]) & 0xff));
141         return (float) d;
142       }
143
144     }
145   }
146
147   private static float[] fracIEEE;
148
149   private static void setFracIEEE() {
150     fracIEEE = new float[270];
151     for (int i = 0; i < 270; i++)
152       fracIEEE[i] = (float) Math.pow(2, i - 141);
153     //    System.out.println(fracIEEE[0] + "  " + Parser.FLOAT_MIN_SAFE);
154     //    System.out.println(fracIEEE[269] + "  " + Float.MAX_VALUE);
155   }
156
157   /**
158    * only concerned about reasonable float values here -- private but not designated; called by JavaScript
159    * 
160    * @param f
161    * @param i
162    * @return f * 2^i
163    */
164   static double shiftIEEE(double f, int i) {
165     if (f == 0 || i < -140)
166       return 0;
167     if (i > 128)
168       return Float.MAX_VALUE;
169     return f * fracIEEE[i + 140];
170   }
171
172 //  static {
173 //    setFracIEEE();
174 //    for (int i = -50; i < 50; i++) {
175 //      float f = i * (float) (Math.random() * Math.pow(2, Math.random() * 100 - 50));
176 //      int x = Float.floatToIntBits(f);
177 //      int m = ((x & 0x7F800000) >> 23);
178 //      float f1 = (float) (f == 0 ? 0 : ((x & 0x80000000) == 0 ? 1 : -1) * shiftIEEE((x & 0x7FFFFF) | 0x800000, m - 149));
179 //      System.out.println(f + "  " + f1);
180 //    }
181 //    System.out.println("binarydo");
182 //  }
183
184
185
186 }