/* Copyright (C) 1998, 1999 Cygnus Solutions This file is part of libgcj. This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ package java.lang; /** * @author Warren Levy * @date September 18, 1998. */ /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 * "The Java Language Specification", ISBN 0-201-63451-1 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com. * Status: Believed complete and correct. */ public final class Long extends Number implements Comparable { public static final long MAX_VALUE = 0x7FFFFFFFFFFFFFFFL; public static final long MIN_VALUE = 0x8000000000000000L; // This initialization is seemingly circular, but it is accepted // by javac, and is handled specially by gcc. public static final Class TYPE = long.class; /* The long value of the instance. */ private long value; public Long(long val) { value = val; } public Long(String str) throws NumberFormatException { value = parseLong(str, 10); } public byte byteValue() { return (byte) value; } public double doubleValue() { return (double) value; } public float floatValue() { return (float) value; } public int intValue() { return (int) value; } public long longValue() { return value; } public short shortValue() { return (short) value; } // Added in JDK 1.2 public int compareTo(Long anotherLong) { if (this.value == anotherLong.value) return 0; // Returns just -1 or 1 on inequality; doing math might overflow the long. if (this.value > anotherLong.value) return 1; return -1; } // Added in JDK 1.2 public int compareTo(Object o) throws ClassCastException { if (!(o instanceof Long)) throw new ClassCastException(); return this.compareTo((Long) o); } // Added in JDK 1.2 public static Long decode(String str) throws NumberFormatException { boolean isNeg = false; int index = 0; int radix = 10; final int len; if (str == null || (len = str.length()) == 0) throw new NumberFormatException(); // Negative numbers are always radix 10. if (str.charAt(0) == '-') { radix = 10; index++; isNeg = true; } else if (str.charAt(index) == '#') { radix = 16; index++; } else if (str.charAt(index) == '0') { // Check if str is just "0" if (len == 1) return new Long(0L); index++; if (str.charAt(index) == 'x') { radix = 16; index++; } else radix = 8; } if (index >= len) throw new NumberFormatException(); return new Long(parseLong(str, index, len, isNeg, radix)); } public boolean equals(Object obj) { return (obj != null && (obj instanceof Long) && ((Long) obj).value == value); } public static Long getLong(String prop) { return getLong(prop, null); } public static Long getLong(String prop, long defval) { Long val = getLong(prop, null); return val == null ? new Long(defval) : val; } public static Long getLong(String prop, Long defobj) { try { return decode(System.getProperty(prop)); } catch (NumberFormatException ex) { return defobj; } } public int hashCode() { return (int)(this.longValue()^(this.longValue()>>>32)); } public static long parseLong(String str) throws NumberFormatException { return parseLong(str, 10); } public static long parseLong(String str, int radix) throws NumberFormatException { final int len; if (str == null || (len = str.length()) == 0 || radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) throw new NumberFormatException(); boolean isNeg = false; int index = 0; if (str.charAt(index) == '-') if (len > 1) { isNeg = true; index++; } else throw new NumberFormatException(); return parseLong(str, index, len, isNeg, radix); } private static long parseLong(String str, int index, int len, boolean isNeg, int radix) throws NumberFormatException { long val = 0; int digval; long max = MAX_VALUE / radix; // We can't directly write `max = (MAX_VALUE + 1) / radix'. // So instead we fake it. if (isNeg && MAX_VALUE % radix == radix - 1) ++max; for ( ; index < len; index++) { if (val < 0 || val > max) throw new NumberFormatException(); if ((digval = Character.digit(str.charAt(index), radix)) < 0) throw new NumberFormatException(); // Throw an exception for overflow if result is negative. // However, we special-case the most negative value. val = val * radix + digval; if (val < 0 && (! isNeg || val != MIN_VALUE)) throw new NumberFormatException(); } return isNeg ? -(val) : val; } public static String toBinaryString(long num) { return toUnsignedString(num, 1); } public static String toHexString(long num) { return toUnsignedString(num, 4); } public static String toOctalString(long num) { return toUnsignedString(num, 3); } private static String toUnsignedString(long num, int exp) { // Use an array large enough for a binary number. int radix = 1 << exp; long mask = radix - 1; char[] buffer = new char[64]; int i = 64; do { buffer[--i] = Character.forDigit((int) (num & mask), radix); num = num >>> exp; } while (num != 0); return String.valueOf(buffer, i, 64-i); } public String toString() { return toString(this.value); } public static String toString(long num) { // Use the Integer toString for efficiency if possible. if (num <= Integer.MAX_VALUE && num >= Integer.MIN_VALUE) return Integer.toString((int) num); // Use an arrary large enough for "-9223372036854775808"; i.e. 11 chars. char[] buffer = new char[20]; int i = 20; boolean isNeg; if (num < 0) { isNeg = true; num = -(num); if (num < 0) { // Must be MIN_VALUE, so handle this special case. buffer[--i] = '8'; num = 922337203685477580L; } } else isNeg = false; do { buffer[--i] = (char) ((int) '0' + (num % 10)); num /= 10; } while (num > 0); if (isNeg) buffer[--i] = '-'; return String.valueOf(buffer, i, 20-i); } public static String toString(long num, int radix) { // Use optimized method for the typical case. if (radix == 10 || radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) return toString(num); // Use the Integer toString for efficiency if possible. if (num <= Integer.MAX_VALUE && num >= Integer.MIN_VALUE) return Integer.toString((int) num, radix); // For negative numbers, print out the absolute value w/ a leading '-'. // Use an array large enough for a binary number. char[] buffer = new char[65]; int i = 65; boolean isNeg; if (num < 0) { isNeg = true; num = -(num); // When the value is MIN_VALUE, it overflows when made positive if (num < 0) { buffer[--i] = Character.forDigit((int) (-(num + radix) % radix), radix); num = -(num / radix); } } else isNeg = false; do { buffer[--i] = Character.forDigit((int) (num % radix), radix); num /= radix; } while (num > 0); if (isNeg) buffer[--i] = '-'; return String.valueOf(buffer, i, 65-i); } public static Long valueOf(String str) throws NumberFormatException { return new Long(parseLong(str, 10)); } public static Long valueOf(String str, int radix) throws NumberFormatException { return new Long(parseLong(str, radix)); } }