![JAR search and dependency download from the Maven repository](/logo.png)
com.ericsson.otp.erlang.OtpErlangLong Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jinterface Show documentation
Show all versions of jinterface Show documentation
Jinterface Java package contains java classes, which help you integrate programs written in Java with Erlang.
Erlang is a programming language designed at the Ericsson Computer Science Laboratory.
/*
* %CopyrightBegin%
*
* Copyright Ericsson AB 2000-2009. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* %CopyrightEnd%
*/
package com.ericsson.otp.erlang;
import java.io.Serializable;
import java.math.BigInteger;
/**
* Provides a Java representation of Erlang integral types. Erlang does not
* distinguish between different integral types, however this class and its
* subclasses {@link OtpErlangByte}, {@link OtpErlangChar},
* {@link OtpErlangInt}, and {@link OtpErlangShort} attempt to map the Erlang
* types onto the various Java integral types. Two additional classes,
* {@link OtpErlangUInt} and {@link OtpErlangUShort} are provided for Corba
* compatibility. See the documentation for IC for more information.
*/
public class OtpErlangLong extends OtpErlangObject implements Serializable,
Cloneable {
// don't change this!
static final long serialVersionUID = 1610466859236755096L;
private long val;
private BigInteger bigVal = null;
/**
* Create an Erlang integer from the given value.
*
* @param l
* the long value to use.
*/
public OtpErlangLong(final long l) {
val = l;
}
/**
* Create an Erlang integer from the given value.
*
* @param val
* the long value to use.
*/
public OtpErlangLong(final BigInteger v) {
if (v == null) {
throw new java.lang.NullPointerException();
}
if (v.bitLength() < 64) {
val = v.longValue();
} else {
bigVal = v;
}
}
/**
* Create an Erlang integer from a stream containing an integer encoded in
* Erlang external format.
*
* @param buf
* the stream containing the encoded value.
*
* @exception OtpErlangDecodeException
* if the buffer does not contain a valid external
* representation of an Erlang integer.
*/
public OtpErlangLong(final OtpInputStream buf)
throws OtpErlangDecodeException {
final byte[] b = buf.read_integer_byte_array();
try {
val = OtpInputStream.byte_array_to_long(b, false);
} catch (final OtpErlangDecodeException e) {
bigVal = new BigInteger(b);
}
}
/**
* Get this number as a BigInteger.
*
* @return the value of this number, as a BigInteger.
*/
public BigInteger bigIntegerValue() {
if (bigVal != null) {
return bigVal;
} else {
return BigInteger.valueOf(val);
}
}
/**
* Get this number as a long, or rather truncate all but the least
* significant 64 bits from the 2's complement representation of this number
* and return them as a long.
*
* @return the value of this number, as a long.
*/
public long longValue() {
if (bigVal != null) {
return bigVal.longValue();
} else {
return val;
}
}
/**
* Determine if this value can be represented as a long without truncation.
*
* @return true if this value fits in a long, false otherwise.
*/
public boolean isLong() {
// To just chech this.bigVal is a wee bit to simple, since
// there just might have be a mean bignum that arrived on
// a stream, and was a long disguised as more than 8 byte integer.
if (bigVal != null) {
return bigVal.bitLength() < 64;
}
return true;
}
/**
* Determine if this value can be represented as an unsigned long without
* truncation, that is if the value is non-negative and its bit pattern
* completely fits in a long.
*
* @return true if this value is non-negative and fits in a long false
* otherwise.
*/
public boolean isULong() {
// Here we have the same problem as for isLong(), plus
// the whole range 1<<63 .. (1<<64-1) is allowed.
if (bigVal != null) {
return bigVal.signum() >= 0 && bigVal.bitLength() <= 64;
}
return val >= 0;
}
/**
* Returns the number of bits in the minimal two's-complement representation
* of this BigInteger, excluding a sign bit.
*
* @return number of bits in the minimal two's-complement representation of
* this BigInteger, excluding a sign bit.
*/
public int bitLength() {
if (bigVal != null) {
return bigVal.bitLength();
}
if (val == 0 || val == -1) {
return 0;
} else {
// Binary search for bit length
int i = 32; // mask length
long m = (1L << i) - 1; // AND mask with ones in little end
if (val < 0) {
m = ~m; // OR mask with ones in big end
for (int j = i >> 1; j > 0; j >>= 1) { // mask delta
if ((val | m) == val) { // mask >= enough
i -= j;
m >>= j; // try less bits
} else {
i += j;
m <<= j; // try more bits
}
}
if ((val | m) != val) {
i++; // mask < enough
}
} else {
for (int j = i >> 1; j > 0; j >>= 1) { // mask delta
if ((val & m) == val) { // mask >= enough
i -= j;
m >>= j; // try less bits
} else {
i += j;
m = m << j | m; // try more bits
}
}
if ((val & m) != val) {
i++; // mask < enough
}
}
return i;
}
}
/**
* Return the signum function of this object.
*
* @return -1, 0 or 1 as the value is negative, zero or positive.
*/
public int signum() {
if (bigVal != null) {
return bigVal.signum();
} else {
return val > 0 ? 1 : val < 0 ? -1 : 0;
}
}
/**
* Get this number as an int.
*
* @return the value of this number, as an int.
*
* @exception OtpErlangRangeException
* if the value is too large to be represented as an int.
*/
public int intValue() throws OtpErlangRangeException {
final long l = longValue();
final int i = (int) l;
if (i != l) {
throw new OtpErlangRangeException("Value too large for int: " + val);
}
return i;
}
/**
* Get this number as a non-negative int.
*
* @return the value of this number, as an int.
*
* @exception OtpErlangRangeException
* if the value is too large to be represented as an int,
* or if the value is negative.
*/
public int uIntValue() throws OtpErlangRangeException {
final long l = longValue();
final int i = (int) l;
if (i != l) {
throw new OtpErlangRangeException("Value too large for int: " + val);
} else if (i < 0) {
throw new OtpErlangRangeException("Value not positive: " + val);
}
return i;
}
/**
* Get this number as a short.
*
* @return the value of this number, as a short.
*
* @exception OtpErlangRangeException
* if the value is too large to be represented as a
* short.
*/
public short shortValue() throws OtpErlangRangeException {
final long l = longValue();
final short i = (short) l;
if (i != l) {
throw new OtpErlangRangeException("Value too large for short: "
+ val);
}
return i;
}
/**
* Get this number as a non-negative short.
*
* @return the value of this number, as a short.
*
* @exception OtpErlangRangeException
* if the value is too large to be represented as a
* short, or if the value is negative.
*/
public short uShortValue() throws OtpErlangRangeException {
final long l = longValue();
final short i = (short) l;
if (i != l) {
throw new OtpErlangRangeException("Value too large for short: "
+ val);
} else if (i < 0) {
throw new OtpErlangRangeException("Value not positive: " + val);
}
return i;
}
/**
* Get this number as a char.
*
* @return the char value of this number.
*
* @exception OtpErlangRangeException
* if the value is too large to be represented as a char.
*/
public char charValue() throws OtpErlangRangeException {
final long l = longValue();
final char i = (char) l;
if (i != l) {
throw new OtpErlangRangeException("Value too large for char: "
+ val);
}
return i;
}
/**
* Get this number as a byte.
*
* @return the byte value of this number.
*
* @exception OtpErlangRangeException
* if the value is too large to be represented as a byte.
*/
public byte byteValue() throws OtpErlangRangeException {
final long l = longValue();
final byte i = (byte) l;
if (i != l) {
throw new OtpErlangRangeException("Value too large for byte: "
+ val);
}
return i;
}
/**
* Get the string representation of this number.
*
* @return the string representation of this number.
*/
@Override
public String toString() {
if (bigVal != null) {
return "" + bigVal;
} else {
return "" + val;
}
}
/**
* Convert this number to the equivalent Erlang external representation.
*
* @param buf
* an output stream to which the encoded number should be
* written.
*/
@Override
public void encode(final OtpOutputStream buf) {
if (bigVal != null) {
buf.write_big_integer(bigVal);
} else {
buf.write_long(val);
}
}
/**
* Determine if two numbers are equal. Numbers are equal if they contain the
* same value.
*
* @param o
* the number to compare to.
*
* @return true if the numbers have the same value.
*/
@Override
public boolean equals(final Object o) {
if (!(o instanceof OtpErlangLong)) {
return false;
}
final OtpErlangLong that = (OtpErlangLong) o;
if (bigVal != null && that.bigVal != null) {
return bigVal.equals(that.bigVal);
} else if (bigVal == null && that.bigVal == null) {
return val == that.val;
}
return false;
}
@Override
protected int doHashCode() {
if (bigVal != null) {
return bigVal.hashCode();
} else {
return BigInteger.valueOf(val).hashCode();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy