@@ -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 }
@@ -121,6 +154,43 @@ public static long reverse(long l) {
121154 return LongUtils .fromBits (Integer .reverse (high ), Integer .reverse (low ));
122155 }
123156
157+ public static long parseUnsignedLong (String s ) throws NumberFormatException {
158+ return parseUnsignedLong (s , 10 );
159+ }
160+
161+ public static long parseUnsignedLong (String s , int radix ) throws NumberFormatException {
162+ return __parseAndValidateUnsignedLong (s , radix );
163+ }
164+
165+ public static long remainderUnsigned (long dividend , long divisor ) {
166+ if (divisor < 0 ) { // i.e., divisor >= 2^63:
167+ if (compare (dividend , divisor ) < 0 ) {
168+ return dividend ; // dividend < divisor
169+ } else {
170+ return dividend - divisor ; // dividend >= divisor
171+ }
172+ }
173+
174+ // Optimization - use signed modulus if dividend < 2^63
175+ if (dividend >= 0 ) {
176+ return dividend % divisor ;
177+ }
178+
179+ /*
180+ * Otherwise, approximate the quotient, check, and correct if necessary. Our approximation is
181+ * guaranteed to be either exact or one less than the correct value. This follows from fact
182+ * that floor(floor(x)/i) == floor(x/i) for any real x and integer i != 0. The proof is not
183+ * quite trivial.
184+ */
185+ long quotient = ((dividend >>> 1 ) / divisor ) << 1 ;
186+ long rem = dividend - quotient * divisor ;
187+ if (compare (rem , divisor ) >= 0 ) {
188+ return rem - divisor ;
189+ } else {
190+ return rem ;
191+ }
192+ }
193+
124194 public static long reverseBytes (long l ) {
125195 int high = LongUtils .getHighBits (l );
126196 int low = (int ) l ;
@@ -163,15 +233,15 @@ public static long sum(long a, long b) {
163233 }
164234
165235 public static String toBinaryString (long value ) {
166- return toPowerOfTwoUnsignedString (value , 1 );
236+ return toUnsignedString (value , 2 );
167237 }
168238
169239 public static String toHexString (long value ) {
170- return toPowerOfTwoUnsignedString (value , 4 );
240+ return toUnsignedString (value , 16 );
171241 }
172242
173243 public static String toOctalString (long value ) {
174- return toPowerOfTwoUnsignedString (value , 3 );
244+ return toUnsignedString (value , 8 );
175245 }
176246
177247 public static String toString (long value ) {
@@ -219,11 +289,89 @@ public static String toString(long value, int intRadix) {
219289
220290 public static Long valueOf (long l ) {
221291 if (l > -129 && l < 128 ) {
222- return BoxedValues .get (l );
292+ return BoxedValues .get (l );
223293 }
224294 return new Long (l );
225295 }
226296
297+ public static String toUnsignedString (long value ) {
298+ return toUnsignedString (value , 10 );
299+ }
300+
301+ public static String toUnsignedString (long value , int intRadix ) {
302+ if (fitsInUint (value )) {
303+ return Integer .toUnsignedString ((int ) value , intRadix );
304+ }
305+
306+ if (intRadix < Character .MIN_RADIX || intRadix > Character .MAX_RADIX ) {
307+ intRadix = 10 ;
308+ }
309+
310+ if (isPowerOfTwo (intRadix )) {
311+ return toPowerOfTwoUnsignedString (value , intRadix );
312+ }
313+
314+ if (value >= 0 ) {
315+ return toString (value , intRadix );
316+ }
317+
318+ // Convert radix to long before hand to avoid costly conversion on each iteration.
319+ long radix = intRadix ;
320+ if (intRadix == 10 ) {
321+ long quotient = divideUnsigned (value , radix );
322+ int rem = (int ) (value - quotient * radix );
323+ return toString (quotient ) + rem ;
324+ }
325+
326+ int bufLen = intRadix < 8 ? 65 : 23 ; // Max chars in result (conservative)
327+ char [] buf = new char [bufLen ];
328+ int cursor = bufLen ;
329+ if (value < 0 ) {
330+ // Separate off the last digit using unsigned division. That will leave
331+ // a number that is nonnegative as a signed integer.
332+ long quotient = divideUnsigned (value , radix );
333+ int rem = (int ) (value - quotient * radix );
334+ buf [--cursor ] = Character .forDigit (rem , intRadix );
335+ value = quotient ;
336+ }
337+
338+ // Simple modulo/division approach
339+ while (value > 0 ) {
340+ buf [--cursor ] = Character .forDigit ((int ) (value % radix ), intRadix );
341+ value /= radix ;
342+ }
343+
344+ return new String (buf , cursor , buf .length - cursor );
345+ }
346+
347+ private static String toPowerOfTwoUnsignedString (long value , int radix ) {
348+ final int shift = log2 (radix );
349+
350+ final int mask = radix - 1 ;
351+ final int bufSize = 64 / shift + 1 ;
352+ char [] buf = new char [bufSize ];
353+ int pos = bufSize ;
354+ do {
355+ buf [--pos ] = Character .forDigit (((int ) value ) & mask );
356+ value >>>= shift ;
357+ } while (value != 0 );
358+
359+ return String .valueOf (buf , pos , bufSize - pos );
360+ }
361+
362+ private static boolean isPowerOfTwo (int x ) {
363+ return (x & (x - 1 )) == 0 ;
364+ }
365+
366+ private static int log2 (int x ) {
367+ return (Integer .SIZE - 1 ) - Integer .numberOfLeadingZeros (x );
368+ }
369+
370+ static boolean fitsInUint (long value ) {
371+ int highBits = (int ) (value >> 32 );
372+ return highBits == 0 ;
373+ }
374+
227375 public static Long valueOf (String s ) throws NumberFormatException {
228376 return valueOf (s , 10 );
229377 }
0 commit comments