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