@@ -24,7 +24,7 @@ public final class Long extends Number implements Comparable<Long> {
2424 /** Use nested class to avoid clinit on outer. */
2525 static class BoxedValues {
2626 // Box values according to JLS - between -128 and 127
27- static Long [] boxedValues = new Long [256 ];
27+ static final Long [] boxedValues = new Long [256 ];
2828
2929 @ HasNoSideEffects
3030 private static Long get (long l ) {
@@ -59,11 +59,44 @@ public static int compare(long x, long y) {
5959 }
6060 }
6161
62+ public static int compareUnsigned (long a , long b ) {
63+ return compare (a ^ MIN_VALUE , b ^ MIN_VALUE );
64+ }
65+
6266 public static Long decode (String s ) throws NumberFormatException {
6367 __Decode decode = __decodeNumberString (s );
6468 return valueOf (decode .payload , decode .radix );
6569 }
6670
71+ public static long divideUnsigned (long dividend , long divisor ) {
72+ if (divisor < 0 ) { // i.e., divisor >= 2^63:
73+ if (compare (dividend , divisor ) < 0 ) {
74+ return 0 ; // dividend < divisor
75+ } else {
76+ return 1 ; // dividend >= divisor
77+ }
78+ }
79+
80+ // Optimization - use signed division if dividend < 2^63
81+ if (dividend >= 0 ) {
82+ return dividend / divisor ;
83+ }
84+
85+ /*
86+ * Otherwise, approximate the quotient, check, and correct if necessary. Our approximation is
87+ * guaranteed to be either exact or one less than the correct value. This follows from fact
88+ * that floor(floor(x)/i) == floor(x/i) for any real x and integer i != 0. The proof is not
89+ * quite trivial.
90+ */
91+ long quotient = ((dividend >>> 1 ) / divisor ) << 1 ;
92+ long rem = dividend - quotient * divisor ;
93+ if (compare (rem , divisor ) >= 0 ) {
94+ return quotient + 1 ;
95+ } else {
96+ return quotient ;
97+ }
98+ }
99+
67100 public static int hashCode (long l ) {
68101 return LongUtils .getHighBits (l ) ^ (int ) l ;
69102 }
@@ -115,12 +148,50 @@ public static long parseLong(String s, int radix) throws NumberFormatException {
115148 return __parseAndValidateLong (s , radix );
116149 }
117150
151+ HEAD
118152 public static long reverse (long l ) {
119153 int high = LongUtils .getHighBits (l );
120154 int low = (int ) l ;
121155 return LongUtils .fromBits (Integer .reverse (high ), Integer .reverse (low ));
122156 }
123157
158+ public static long parseUnsignedLong (String s ) throws NumberFormatException {
159+ return parseUnsignedLong (s , 10 );
160+ }
161+
162+ public static long parseUnsignedLong (String s , int radix ) throws NumberFormatException {
163+ return __parseAndValidateUnsignedLong (s , radix );
164+ }
165+
166+ public static long remainderUnsigned (long dividend , long divisor ) {
167+ if (divisor < 0 ) { // i.e., divisor >= 2^63:
168+ if (compare (dividend , divisor ) < 0 ) {
169+ return dividend ; // dividend < divisor
170+ } else {
171+ return dividend - divisor ; // dividend >= divisor
172+ }
173+ }
174+
175+ // Optimization - use signed modulus if dividend < 2^63
176+ if (dividend >= 0 ) {
177+ return dividend % divisor ;
178+ }
179+
180+ /*
181+ * Otherwise, approximate the quotient, check, and correct if necessary. Our approximation is
182+ * guaranteed to be either exact or one less than the correct value. This follows from fact
183+ * that floor(floor(x)/i) == floor(x/i) for any real x and integer i != 0. The proof is not
184+ * quite trivial.
185+ */
186+ long quotient = ((dividend >>> 1 ) / divisor ) << 1 ;
187+ long rem = dividend - quotient * divisor ;
188+ if (compare (rem , divisor ) >= 0 ) {
189+ return rem - divisor ;
190+ } else {
191+ return rem ;
192+ }
193+ }
194+
124195 public static long reverseBytes (long l ) {
125196 int high = LongUtils .getHighBits (l );
126197 int low = (int ) l ;
@@ -163,15 +234,15 @@ public static long sum(long a, long b) {
163234 }
164235
165236 public static String toBinaryString (long value ) {
166- return toPowerOfTwoUnsignedString (value , 1 );
237+ return toUnsignedString (value , 2 );
167238 }
168239
169240 public static String toHexString (long value ) {
170- return toPowerOfTwoUnsignedString (value , 4 );
241+ return toUnsignedString (value , 16 );
171242 }
172243
173244 public static String toOctalString (long value ) {
174- return toPowerOfTwoUnsignedString (value , 3 );
245+ return toUnsignedString (value , 8 );
175246 }
176247
177248 public static String toString (long value ) {
@@ -219,11 +290,89 @@ public static String toString(long value, int intRadix) {
219290
220291 public static Long valueOf (long l ) {
221292 if (l > -129 && l < 128 ) {
222- return BoxedValues .get (l );
293+ return BoxedValues .get (l );
223294 }
224295 return new Long (l );
225296 }
226297
298+ public static String toUnsignedString (long value ) {
299+ return toUnsignedString (value , 10 );
300+ }
301+
302+ public static String toUnsignedString (long value , int intRadix ) {
303+ if (fitsInUint (value )) {
304+ return Integer .toUnsignedString ((int ) value , intRadix );
305+ }
306+
307+ if (intRadix < Character .MIN_RADIX || intRadix > Character .MAX_RADIX ) {
308+ intRadix = 10 ;
309+ }
310+
311+ if (isPowerOfTwo (intRadix )) {
312+ return toPowerOfTwoUnsignedString (value , intRadix );
313+ }
314+
315+ if (value >= 0 ) {
316+ return toString (value , intRadix );
317+ }
318+
319+ // Convert radix to long before hand to avoid costly conversion on each iteration.
320+ long radix = intRadix ;
321+ if (intRadix == 10 ) {
322+ long quotient = divideUnsigned (value , radix );
323+ int rem = (int ) (value - quotient * radix );
324+ return toString (quotient ) + rem ;
325+ }
326+
327+ int bufLen = intRadix < 8 ? 65 : 23 ; // Max chars in result (conservative)
328+ char [] buf = new char [bufLen ];
329+ int cursor = bufLen ;
330+ if (value < 0 ) {
331+ // Separate off the last digit using unsigned division. That will leave
332+ // a number that is nonnegative as a signed integer.
333+ long quotient = divideUnsigned (value , radix );
334+ int rem = (int ) (value - quotient * radix );
335+ buf [--cursor ] = Character .forDigit (rem , intRadix );
336+ value = quotient ;
337+ }
338+
339+ // Simple modulo/division approach
340+ while (value > 0 ) {
341+ buf [--cursor ] = Character .forDigit ((int ) (value % radix ), intRadix );
342+ value /= radix ;
343+ }
344+
345+ return new String (buf , cursor , buf .length - cursor );
346+ }
347+
348+ private static String toPowerOfTwoUnsignedString (long value , int radix ) {
349+ final int shift = log2 (radix );
350+
351+ final int mask = radix - 1 ;
352+ final int bufSize = 64 / shift + 1 ;
353+ char [] buf = new char [bufSize ];
354+ int pos = bufSize ;
355+ do {
356+ buf [--pos ] = Character .forDigit (((int ) value ) & mask );
357+ value >>>= shift ;
358+ } while (value != 0 );
359+
360+ return String .valueOf (buf , pos , bufSize - pos );
361+ }
362+
363+ private static boolean isPowerOfTwo (int x ) {
364+ return (x & (x - 1 )) == 0 ;
365+ }
366+
367+ private static int log2 (int x ) {
368+ return (Integer .SIZE - 1 ) - Integer .numberOfLeadingZeros (x );
369+ }
370+
371+ static boolean fitsInUint (long value ) {
372+ int highBits = (int ) (value >> 32 );
373+ return highBits == 0 ;
374+ }
375+
227376 public static Long valueOf (String s ) throws NumberFormatException {
228377 return valueOf (s , 10 );
229378 }
0 commit comments