package org.simantics.databoard.primitives; import java.math.BigInteger; /** * Unsigned immutable 64-bit integer value. The value is between 0 and 18446744073709551615. * * @author Toni Kalajainen */ public abstract class UnsignedLong extends Number implements Comparable { static final long serialVersionUID = 1L; static final long L_MIN_VALUE = 0; static final BigInteger HALF = new BigInteger("9223372036854775808"); // 2^63 static final BigInteger BI_MIN_VALUE = new BigInteger("0"); static final BigInteger BI_MAX_VALUE = new BigInteger("18446744073709551615"); // 2^64-1 public static final UnsignedLong MIN_VALUE, MAX_VALUE, ZERO; /** Value container */ long value; /** * Get cached or create new immutable unsigned long * * @param value * @return immutable unsigned long */ public static UnsignedLong valueOf(long value) { if ( value>=0 && value=0 && bits0) throw new IllegalArgumentException("Argument is not within range"); this.value = value.compareTo(HALF)<0 ? value.longValue() : value.subtract(HALF).longValue() | 0x80000000l; } public Mutable(String stringValue) throws IllegalArgumentException { long value = Long.parseLong(stringValue); if ( value0) throw new IllegalArgumentException("Argument is not within range"); this.value = value.compareTo(HALF)<0 ? value.longValue() : value.subtract(HALF).longValue() | 0x80000000l; } } public final static class Immutable extends UnsignedLong { private static final long serialVersionUID = 1L; Immutable() {} public Immutable(int value) throws IllegalArgumentException { if ( value0) throw new IllegalArgumentException("Argument is not within range"); this.value = value.compareTo(HALF)<0 ? value.longValue() : value.subtract(HALF).longValue() | 0x80000000l; } public Immutable(String stringValue) throws IllegalArgumentException { long value = Long.parseLong(stringValue); if ( value=0 ? BigInteger.valueOf(value) : BigInteger.valueOf(value & 0x7fffffff).add(HALF); } @Override public boolean equals(Object obj) { if (obj == null) return false; if (obj == this) return true; if (obj instanceof UnsignedLong == false) return false; UnsignedLong other = (UnsignedLong) obj; return value == other.value; } @Override public String toString() { return value>=0 ? Long.toString(value) : toBigInteger().toString(); } @Override public int compareTo(Number obj) { return value>=0 ? Long.signum( value - obj.longValue() ) : 1; } @Override public int hashCode() { return (int)value | (int)(value>>32); } // Initialize Cache private static int CACHE_SIZE = 16; private static UnsignedLong.Immutable[] CACHE; static { CACHE = new UnsignedLong.Immutable[CACHE_SIZE]; for (int i=0; i