001 
002 /*
003  *  JScripter Emulation 1.0 - To Script Java
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package org.jscripter.emu.java.lang;
021 
022 import js.*;
023 
024 /**
025  * <p><b>Internally</b> represents primitive long values, emulating a standard <tt>java.lang</tt> interface or 
026  * class with the same simple name as this one.</p>
027  * <p>This interface or class is only used internally by JS re-compiler implementations.</p>
028  * <p>Please refer to <a href="http://java.sun.com/docs/">the Java API Standards</a> for detail description of the original class or interface.</p>
029  * 
030  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
031  * 
032  * @javascript Re-compilers must redirect the resolution of the emulated original Java class or interface to this one.
033  */
034 public final class Long extends Number implements Comparable<Long>
035 {
036     /**
037      * <p>Internally stores a constant holding the minimum value a long can have, -2<sup>63</sup>.</p>
038      * @since 1.0
039      * @javascript Re-compilers must report error on end-users directly using this field.
040      */
041     public static final long MIN_VALUE = 0x8000000000000000L;
042     /**
043      * <p>Internally stores a constant holding the maximum value a long can have, 2<sup>63</sup>-1.</p>
044      * @since 1.0
045      * @javascript Re-compilers must report error on end-users directly using this field.
046      */
047     public static final long MAX_VALUE = 0x7FFFFFFFFFFFFFFFL;
048     /**
049      * <p>Internally stores the number of bits used to represent a long value in two's complement binary form.</p>
050      * @since 1.0
051      * @javascript Re-compilers must report error on end-users directly using this field.
052      */
053     public static final int SIZE = 64;
054 
055     /**
056      * <p>Returns the number of one-bits in the two's complement binary representation of the 
057      * specified long value.</p>
058      * @param i A long value to count population.
059      * @return The number of one-bits in the two's complement binary representation of the 
060      * specified value.
061      * @since 1.0
062      * @javascript Re-compilers must report error on end-users directly using this method.
063      */
064     public static final int bitCount(long i) {
065         int cnt = 0;
066         for (long q = MIN_VALUE; q > 0; q = q >> 1) {
067             if ((q & i) != 0) {
068                 cnt++;
069             }
070         }
071         return cnt;
072     }
073 
074     /**
075      * <p>Decodes a string into a {@link Long}.</p>
076      * @param s A string to decode.
077      * @return A {@link Long} represented by <tt>s</tt>.
078      * @throws java.lang.NumberFormatException if the string does not contain a parsable long.
079      * @since 1.0
080      * @javascript Re-compilers must report error on end-users directly using this method.
081      */
082     public static final java.lang.Long decode(java.lang.String s) throws java.lang.NumberFormatException {
083         try {
084             return Js.parseInt(s).longValue();
085         } catch (java.lang.Exception e) {
086             throw new java.lang.NumberFormatException(e.toString());
087         }
088     }
089 
090     /**
091      * <p>Returns a long value with at most a single one-bit, in the position of the highest-order 
092      * ("leftmost") one-bit in the specified long value.</p>
093      * <p>This method returns 0 if the specified value has no one-bits in its two's complement binary 
094      * representation, that is, if it is equal to 0.</p>
095      * @param i A long value.
096      * @return A long value with a single one-bit, in the position of the highest-order one-bit in the 
097      * specified value, or 0 if the specified value is itself equal to 0.
098      * @since 1.0
099      * @javascript Re-compilers must report error on end-users directly using this method.
100      */
101     public static final long highestOneBit(long i) {
102         if (i < 0) {
103             return MIN_VALUE;
104         } else {
105             long rtn;
106             for (rtn = 0x4000000000000000L; (rtn >> 1) > i; rtn = rtn >> 1);
107             return rtn;
108         }
109     }
110 
111     /**
112      * <p>Returns a long value with at most a single one-bit, in the position of the lowest-order 
113      * ("rightmost") one-bit in the specified long value.</p>
114      * <p>This method returns 0 if the specified value has no one-bits in its two's complement binary 
115      * representation, that is, if it is equal to 0.</p>
116      * @param i A long value.
117      * @return A long value with a single one-bit, in the position of the lowest-order one-bit in 
118      * the specified value, or 0 if the specified value is itself equal to 0.
119      * @since 1.0
120      * @javascript Re-compilers must report error on end-users directly using this method.
121      */
122     public static final long lowestOneBit (long i) {
123         if (i == 0) {
124             return SIZE;
125         } else {
126             long r = 1;
127             while ((r & i) != 0) {
128                 r = r << 1;
129             }
130             return r;
131         }
132     }
133 
134     /**
135      * <p>Returns the number of zero bits preceding the highest-order ("leftmost") one-bit in the 
136      * two's complement binary representation of the specified long value.</p>
137      * <p>This method returns 64 if the specified value has no one-bits in its two's complement 
138      * representation, i.e., if it is equal to 0.</p>
139      * @param i A long value.
140      * @return The number of zero bits preceding the highest-order ("leftmost") one-bit in the 
141      * two's complement binary representation of the specified long value, or 64 if the value is 
142      * equal to 0.
143      * @since 1.0
144      * @javascript Re-compilers must report error on end-users directly using this method.
145      */
146     public static final int numberOfLeadingZeros(long i) {
147         if (i < 0) {
148             return 0;
149         } else if (i == 0) {
150             return SIZE;
151         } else {
152             return SIZE - 1 - (int)Math.floor(Math.log((double)i) / Math.log(2.0d));
153         }
154     }
155 
156     /**
157      * <p>Returns the number of zero bits following the lowest-order ("rightmost") one-bit in the 
158      * two's complement binary representation of the specified long value.</p>
159      * <p>This method returns 64 if the specified value has no one-bits in its two's complement 
160      * representation, i.e., if it is equal to 0.</p>
161      * @param i A long value.
162      * @return The number of zero bits following the lowest-order ("rightmost") one-bit in the 
163      * two's complement binary representation of the specified long value, or 64 if the value is 
164      * equal to 0.
165      * @since 1.0
166      * @javascript Re-compilers must report error on end-users directly using this method.
167      */
168     public static final int numberOfTrailingZeros(long i) {
169         if (i < 0) {
170             return 0;
171         } else if (i == 0) {
172             return SIZE;
173         } else {
174             int rtn = 0;
175             for (int r = 1; (r & i) != 0; r = r * 2) {
176                 rtn++;
177             }
178             return rtn;
179         }
180     }
181 
182     /**
183      * <p>Parses the string argument as a signed decimal long.</p>
184      * <p>The characters in the string must all be decimal digits, except that the first character 
185      * may be an ASCII minus sign '-' ('-') to indicate a negative value. The resulting long 
186      * value is returned, exactly as if the argument and the radix 10 were given as arguments to 
187      * the {@link #parseLong(String, int)} method.</p>
188      * @param s A string containing the long representation to be parsed.
189      * @return The {@link Long} represented by the string argument in decimal.
190      * @throws java.lang.NumberFormatException if the string does not contain a parsable long.
191      * @since 1.0
192      * @javascript Re-compilers must report error on end-users directly using this method.
193      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
194      */
195     public static final synchronized long parseLong(java.lang.String s) throws java.lang.NumberFormatException {
196         return parseLong(s, 10);
197     }
198 
199     /**
200      * <p>Parses the string argument as a signed long in the radix specified by the second argument.</p>
201      * <p>The characters in the string must all be digits, of the specified radix (as determined by 
202      * whether {@link Character#digit(char, int)} returns a nonnegative value) except that the first 
203      * character may be an ASCII minus sign '-' ('-') to indicate a negative value. The resulting
204      * long value is returned.</p>
205      * @param s A string containing the short representation to be parsed.
206      * @param radix The radix to be used while parsing <tt>s</tt>.
207      * @return The {@link Long} represented by the string argument in the specified radix.
208      * @throws java.lang.NumberFormatException if the string does not contain a parsable long.
209      * @since 1.0
210      * @javascript Re-compilers must report error on end-users directly using this method.
211      */
212     public static final long parseLong(java.lang.String s, int radix)
213             throws java.lang.NumberFormatException {
214         try {
215             java.lang.Number n = Js.parseInt(s);
216             if (Js.llt(n, MIN_VALUE) || Js.lgt(n, MAX_VALUE)) {
217                 throw new java.lang.NumberFormatException("out of bounds");
218             }
219             return n.longValue();
220         } catch (java.lang.Exception e) {
221             throw new java.lang.NumberFormatException(e.toString());
222         }
223     }
224 
225     /**
226      * <p>Returns the value obtained by reversing the order of the bits in the two's complement 
227      * binary representation of the specified long value.</p>
228      * @param i A long to be converted.
229      * @return The value obtained by reversing order of the bits in the specified long value.
230      * @since 1.0
231      * @javascript Re-compilers must report error on end-users directly using this method.
232      */
233     public static final long reverse(long i) {
234         long acc = 0;
235         long front = MIN_VALUE;
236         int back = 1;
237         int swing = SIZE - 1;
238         while (swing > 15) {
239             acc = acc | ((i & front) >> swing) | ((i & back) << swing);
240             swing--;
241             front = front >> 1;
242             back = back << 1;
243         }
244         return acc;
245     }
246 
247     /**
248      * <p>Returns the value obtained by reversing the order of the bytes in the two's complement 
249      * representation of the specified long value.</p>
250      * @param i A long to be converted.
251      * @return The value obtained by reversing the bytes in the specified value.
252      * @since 1.0
253      * @javascript Re-compilers must report error on end-users directly using this method.
254      */
255     public static final long reverseBytes(long i) {
256         return ((i & 0xffL) << 56) | ((i & 0xff00L) << 40)
257          | ((i & 0xff0000L) << 24) | ((i & 0xff000000L) << 8)
258          | ((i & 0xff00000000L) >> 8) | ((i & 0xff0000000000L) >> 24)
259          | ((i & 0xff000000000000L) >> 40) | ((i & 0xff00000000000000L) >> 56);
260     }
261 
262     /**
263      * <p>Returns the value obtained by rotating the two's complement binary representation of the 
264      * specified long value left by the specified number of bits.</p>
265      * <p>Bits shifted out of the left hand, or high-order, side reenter on the right, or low-order.</p>
266      * <p>Note that left rotation with a negative distance is equivalent to right rotation: 
267      * <pre>rotateLeft(i, -distance) == rotateRight(i, distance)</pre>
268      * Note also that rotation by any multiple of 64 is a no-op, so all but the last five bits of 
269      * the rotation distance can be ignored, even if the distance is negative:
270      * <pre>rotateLeft(i, distance) == rotateLeft(i, distance & 0x3F)</pre>
271      * </p>
272      * @param i An long to be shifted.
273      * @return The value obtained by rotating the two's complement binary representation of the 
274      * specified long value left by the specified number of bits.
275      * @since 1.0
276      * @javascript Re-compilers must report error on end-users directly using this method.
277      */
278     public static final long rotateLeft(long i, int distance) {
279         if (distance < 0) {
280             return rotateRight(i, -distance);
281         }
282         distance &= 0x3F;
283         while (distance-- > 0) {
284             i = i << 1 | ((i < 0) ? 1 : 0);
285         }
286         return i;
287     }
288 
289     /**
290      * <p>Returns the value obtained by rotating the two's complement binary representation of the 
291      * specified long value right by the specified number of bits.</p>
292      * <p>Bits shifted out of the right hand, or low-order, side reenter on the left, or high-order.</p>
293      * <p>Note that right rotation with a negative distance is equivalent to left rotation:
294      * <pre>rotateRight(i, -distance) == rotateLeft(i, distance)</pre>
295      * Note also that rotation by any multiple of 64 is a no-op, so all but the last five bits of 
296      * the rotation distance can be ignored, even if the distance is negative:
297      * <pre>rotateRight(i, distance) == rotateRight(i, distance & 0x3F)</pre>
298      * </p>
299      * @param i A long to be shifted.
300      * @return The value obtained by rotating the two's complement binary representation of the 
301      * specified long value right by the specified number of bits.
302      * @since 1.0
303      * @javascript Re-compilers must report error on end-users directly using this method.
304      */
305     public static final long rotateRight(long i, int distance) {
306         if (distance < 0) {
307             return rotateLeft(i, -distance);
308         }
309         distance &= 0x3F;
310         while (distance-- > 0) {
311             i = ((i & 1) == 0 ? 0 : MIN_VALUE) | i >> 1;
312         }
313         return i;
314     }
315 
316     /**
317      * <p>Returns the signum function of the specified long value</p>
318      * @param i A long value.
319      * @return -1 if the specified value is negative; 0 if the specified value is zero; 
320      * and 1 if the specified value is positive.
321      * @since 1.0
322      * @javascript Re-compilers must report error on end-users directly using this method.
323      */
324     public static final int signum(long i) {
325         return ((java.lang.Integer)Js.cond(
326                 Js.eq(i, 0),
327                 0, 
328                 Js.cond(
329                         Js.lt(i, 0),
330                         -1, 
331                         1
332                 )
333         )).intValue();
334     }
335 
336     private static final java.lang.String toBinary(long x, int bm1, int bits) {
337         if (x == 0) {
338             return "0";
339         }
340         java.lang.String s = "";
341         while (x != 0) {
342             int digit = (int) x & bm1;
343             s = Js.add(Integer.digits16.get(digit), s);
344             x = x >>> bits;
345         }
346         return s;
347     }
348 
349     /**
350      * <p>Returns a string representation of the argument as an unsigned value in base 2.</p>
351      * @param x A value to be converted to a string.
352      * @return The string representation of the unsigned value represented by the argument in 
353      * binary (base 2).
354      * @since 1.0
355      * @javascript Re-compilers must report error on end-users directly using this method.
356      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
357      */
358     public static final synchronized java.lang.String toBinaryString(long x) {
359         return toBinary(x, 1, 1);
360     }
361 
362     /**
363      * <p>Returns a string representation of the argument as an unsigned value in base 8.</p>
364      * @param x A value to be converted to a string.
365      * @return The string representation of the unsigned value represented by the argument in 
366      * octal (base 8).
367      * @since 1.0
368      * @javascript Re-compilers must report error on end-users directly using this method.
369      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
370      */
371     public static final synchronized java.lang.String toOctalString(long x) {
372         return toBinary(x, 7, 3);
373     }
374 
375     /**
376      * <p>Returns a string representation of the argument as an unsigned value in base 16.</p>
377      * @param x A value to be converted to a string.
378      * @return The string representation of the unsigned value represented by the argument in 
379      * hexadecimal (base 16).
380      * @since 1.0
381      * @javascript Re-compilers must report error on end-users directly using this method.
382      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
383      */
384     public static final synchronized java.lang.String toHexString(long x) {
385         return toBinary(x, 15, 4);
386     }
387 
388     /**
389      * <p>Returns a string representing the specified long. The radix is assumed to be 10.</p>
390      * @param i A long to be converted.
391      * @return The string representation of the specified long.
392      * @since 1.0
393      * @javascript Re-compilers must report error on end-users directly using this method.
394      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
395      */
396     public static final synchronized java.lang.String toString(long i) {
397         return ((ObjectLike)(java.lang.Object)new Long(i)).toString();
398     }
399 
400     /**
401      * <p>Returns a {@link Long} representing the specified long value.</p>
402      * @param i A long value.
403      * @return A {@link Long} representing <tt>i</tt>.
404      * @since 1.0
405      * @javascript Re-compilers must report error on end-users directly using this method.
406      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
407      */
408     public static final synchronized Long valueOf(long i) {
409         return new Long(i);
410     }
411 
412     /**
413      * <p>Returns a {@link Long} represented by the specified string value.</p>
414      * @param s A string value.
415      * @return A {@link Long} represented by <tt>s</tt>.
416      * @throws java.lang.NumberFormatException if the string does not contain a parsable long.
417      * @since 1.0
418      * @javascript Re-compilers must report error on end-users directly using this method.
419      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
420      */
421     public static final synchronized Long valueOf(java.lang.String s) throws java.lang.NumberFormatException {
422         return new Long(parseLong(s));
423     }
424 
425     /**
426      * <p>Returns a {@link Long} represented by the specified string value when parsed with the radix 
427      * given by the second argument.</p>
428      * @param s A string value.
429      * @param radix The radix to be used in interpreting <tt>s</tt>.
430      * @return A {@link Long} represented by <tt>s</tt> in the specified radix.
431      * @throws java.lang.NumberFormatException if the string does not contain a parsable long.
432      * @since 1.0
433      * @javascript Re-compilers must report error on end-users directly using this method.
434      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
435      */
436     public static final synchronized Long valueOf(java.lang.String s, int radix) throws java.lang.NumberFormatException {
437         return new Long(parseLong(s, radix));
438     }
439 
440     /**
441      * <p>Allocates an {@link Long} representing the long argument.</p>
442      * @param value A long value.
443      * @since 1.0
444      * @javascript Re-compilers must report error on end-users directly using this constructor.
445      * A re-compiler simply replaces an invocation of this constructor with its argument.
446      */
447     public Long(long value) {
448     }
449 
450     /**
451      * <p>Allocates a {@link Long} representing the value indicated by the string parameter.</p>
452      * <p>The string is converted to a long value in exactly the manner used by the {@link #parseLong(String)}
453      * method for radix 10.</p>
454      * @param s A string to be converted to a {@link Long}.
455      * @throws NumberFormatException if the string does not contain a parsable long.
456      * @since 1.0
457      * @javascript Re-compilers must report error on end-users directly using this constructor.
458      * A re-compiler simply replaces an invocation of this constructor with an invocation of 
459      * {@link #valueOf(String)} passing the string argument.
460      */
461     public Long(java.lang.String s) {
462     }
463 
464     /**
465      * <p>Returns the value of this {@link Long} as a byte primitive.</p>
466      * @return The primitive byte value.
467      * @since 1.0
468      * @javascript Re-compilers must report error on end-users directly using this method.
469      * A re-compiler simply replaces an invocation of this native method with the current {@link Long}
470      * involving rounding or truncation necessarily.
471      */
472     @Override
473     public final native byte byteValue();
474     /**
475      * <p>Returns the value of this {@link Long} as a short primitive.</p>
476      * @return The primitive short value.
477      * @since 1.0
478      * @javascript Re-compilers must report error on end-users directly using this method.
479      * A re-compiler simply replaces an invocation of this native method with the current {@link Long}
480      * involving rounding or truncation necessarily.
481      */
482     @Override
483     public final native short shortValue();
484     /**
485      * <p>Returns the value of this {@link Long} as an int primitive.</p>
486      * @return The primitive int value.
487      * @since 1.0
488      * @javascript Re-compilers must report error on end-users directly using this method.
489      * A re-compiler simply replaces an invocation of this native method with the current {@link Long}.
490      * involving rounding or truncation necessarily.
491      */
492     @Override
493     public final native int intValue();
494     /**
495      * <p>Returns the value of this {@link Long} as a long primitive.</p>
496      * @return The primitive long value.
497      * @since 1.0
498      * @javascript Re-compilers must report error on end-users directly using this method.
499      * A re-compiler simply replaces an invocation of this native method with the current {@link Long}.
500      */
501     @Override
502     public final native long longValue();
503     /**
504      * <p>Returns the value of this {@link Long} as a float primitive.</p>
505      * @return The primitive float value.
506      * @since 1.0
507      * @javascript Re-compilers must report error on end-users directly using this method.
508      * A re-compiler simply replaces an invocation of this native method with the current {@link Long}.
509      * involving truncation necessarily.
510      */
511     @Override
512     public final native float floatValue();
513     /**
514      * <p>Returns the value of this {@link Long} as a long primitive.</p>
515      * @return The primitive double value.
516      * @since 1.0
517      * @javascript Re-compilers must report error on end-users directly using this method.
518      * A re-compiler simply replaces an invocation of this native method with the current {@link Long}.
519      */
520     @Override
521     public final native double doubleValue();
522 
523     /**
524      * <p>Compares two {@link Long}s numerically.</p>
525      * @param i The {@link Long} to be compared.
526      * @return 0 if this {@link Long} is equal to the argument {@link Long}; a value less than 0 
527      * if this {@link Long} is numerically less than the argument {@link Long}; and a value greater 
528      * than 0 if this {@link Long} is numerically greater than the argument {@link Long} (signed comparison).
529      * @since 1.0
530      * @javascript Re-compilers must report error on end-users directly using this method.
531      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
532      */
533     public final int compareTo(Long i) {
534         return ((java.lang.Integer)Js.cond(
535                 Js.llt(this, i),
536                 -1, 
537                 Js.cond(
538                         Js.lgt(this, i),
539                         1, 
540                         0
541                 )
542         )).intValue();
543     }
544 
545     /**
546      * <p>Compares this {@link Long} to the specified object.</p>
547      * <p>Returns <tt>true</tt> if and only if the argument is not <tt>null</tt> and is a {@link Long} 
548      * that represents the same value as this {@link Long}.</p>
549      * @param o The object to compare with.
550      * @return <tt>true</tt> if the {@link Long}s represent the same value; <tt>false</tt> otherwise.
551      * @since 1.0
552      * @javascript Re-compilers must report error on end-users directly using this method.
553      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
554      */
555     @Override
556     public final boolean equals(java.lang.Object o) {
557         return Js.eq(this, o);
558     }
559 
560     /**
561      * <p>Returns a hash code for this {@link Long}.</p>
562      * @return A hash code value for this {@link Long}.
563      * @since 1.0
564      * @javascript Re-compilers must report error on end-users directly using this method.
565      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
566      */
567     @Override
568     public final int hashCode() {
569         return intValue();
570     }
571 
572     /**
573      * <p>Returns a string representing this {@link Long}'s value.</p>
574      * <p>The value is converted to signed decimal representation and returned as a string, exactly 
575      * as if the long value were given as an argument to the {@link #toString(long)} method.</p>
576      * @return A string representation of this {@link Long} in base 10.
577      * @since 1.0
578      * @javascript Re-compilers must report error on end-users directly using this method.
579      */
580     @Override
581     public final java.lang.String toString() {
582         return toString(longValue());
583     }
584 }