org.bouncycastle.math.ec.SimpleBigDecimal Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.saml.opensaml.integration Show documentation
Show all versions of com.liferay.saml.opensaml.integration Show documentation
Liferay SAML OpenSAML Integration
package org.bouncycastle.math.ec;
import java.math.BigInteger;
/**
* Class representing a simple version of a big decimal. A
* SimpleBigDecimal
is basically a
* {@link java.math.BigInteger BigInteger} with a few digits on the right of
* the decimal point. The number of (binary) digits on the right of the decimal
* point is called the scale
of the SimpleBigDecimal
.
* Unlike in {@link java.math.BigDecimal BigDecimal}, the scale is not adjusted
* automatically, but must be set manually. All SimpleBigDecimal
s
* taking part in the same arithmetic operation must have equal scale. The
* result of a multiplication of two SimpleBigDecimal
s returns a
* SimpleBigDecimal
with double scale.
*/
class SimpleBigDecimal
//extends Number // not in J2ME - add compatibility class?
{
private static final long serialVersionUID = 1L;
private final BigInteger bigInt;
private final int scale;
/**
* Returns a SimpleBigDecimal
representing the same numerical
* value as value
.
* @param value The value of the SimpleBigDecimal
to be
* created.
* @param scale The scale of the SimpleBigDecimal
to be
* created.
* @return The such created SimpleBigDecimal
.
*/
public static SimpleBigDecimal getInstance(BigInteger value, int scale)
{
return new SimpleBigDecimal(value.shiftLeft(scale), scale);
}
/**
* Constructor for SimpleBigDecimal
. The value of the
* constructed SimpleBigDecimal
equals bigInt /
* 2scale
.
* @param bigInt The bigInt
value parameter.
* @param scale The scale of the constructed SimpleBigDecimal
.
*/
public SimpleBigDecimal(BigInteger bigInt, int scale)
{
if (scale < 0)
{
throw new IllegalArgumentException("scale may not be negative");
}
this.bigInt = bigInt;
this.scale = scale;
}
private void checkScale(SimpleBigDecimal b)
{
if (scale != b.scale)
{
throw new IllegalArgumentException("Only SimpleBigDecimal of " +
"same scale allowed in arithmetic operations");
}
}
public SimpleBigDecimal adjustScale(int newScale)
{
if (newScale < 0)
{
throw new IllegalArgumentException("scale may not be negative");
}
if (newScale == scale)
{
return this;
}
return new SimpleBigDecimal(bigInt.shiftLeft(newScale - scale),
newScale);
}
public SimpleBigDecimal add(SimpleBigDecimal b)
{
checkScale(b);
return new SimpleBigDecimal(bigInt.add(b.bigInt), scale);
}
public SimpleBigDecimal add(BigInteger b)
{
return new SimpleBigDecimal(bigInt.add(b.shiftLeft(scale)), scale);
}
public SimpleBigDecimal negate()
{
return new SimpleBigDecimal(bigInt.negate(), scale);
}
public SimpleBigDecimal subtract(SimpleBigDecimal b)
{
return add(b.negate());
}
public SimpleBigDecimal subtract(BigInteger b)
{
return new SimpleBigDecimal(bigInt.subtract(b.shiftLeft(scale)),
scale);
}
public SimpleBigDecimal multiply(SimpleBigDecimal b)
{
checkScale(b);
return new SimpleBigDecimal(bigInt.multiply(b.bigInt), scale + scale);
}
public SimpleBigDecimal multiply(BigInteger b)
{
return new SimpleBigDecimal(bigInt.multiply(b), scale);
}
public SimpleBigDecimal divide(SimpleBigDecimal b)
{
checkScale(b);
BigInteger dividend = bigInt.shiftLeft(scale);
return new SimpleBigDecimal(dividend.divide(b.bigInt), scale);
}
public SimpleBigDecimal divide(BigInteger b)
{
return new SimpleBigDecimal(bigInt.divide(b), scale);
}
public SimpleBigDecimal shiftLeft(int n)
{
return new SimpleBigDecimal(bigInt.shiftLeft(n), scale);
}
public int compareTo(SimpleBigDecimal val)
{
checkScale(val);
return bigInt.compareTo(val.bigInt);
}
public int compareTo(BigInteger val)
{
return bigInt.compareTo(val.shiftLeft(scale));
}
public BigInteger floor()
{
return bigInt.shiftRight(scale);
}
public BigInteger round()
{
SimpleBigDecimal oneHalf = new SimpleBigDecimal(ECConstants.ONE, 1);
return add(oneHalf.adjustScale(scale)).floor();
}
public int intValue()
{
return floor().intValue();
}
public long longValue()
{
return floor().longValue();
}
/* NON-J2ME compliant.
public double doubleValue()
{
return Double.valueOf(toString()).doubleValue();
}
public float floatValue()
{
return Float.valueOf(toString()).floatValue();
}
*/
public int getScale()
{
return scale;
}
public String toString()
{
if (scale == 0)
{
return bigInt.toString();
}
BigInteger floorBigInt = floor();
BigInteger fract = bigInt.subtract(floorBigInt.shiftLeft(scale));
if (bigInt.signum() == -1)
{
fract = ECConstants.ONE.shiftLeft(scale).subtract(fract);
}
if ((floorBigInt.signum() == -1) && (!(fract.equals(ECConstants.ZERO))))
{
floorBigInt = floorBigInt.add(ECConstants.ONE);
}
String leftOfPoint = floorBigInt.toString();
char[] fractCharArr = new char[scale];
String fractStr = fract.toString(2);
int fractLen = fractStr.length();
int zeroes = scale - fractLen;
for (int i = 0; i < zeroes; i++)
{
fractCharArr[i] = '0';
}
for (int j = 0; j < fractLen; j++)
{
fractCharArr[zeroes + j] = fractStr.charAt(j);
}
String rightOfPoint = new String(fractCharArr);
StringBuffer sb = new StringBuffer(leftOfPoint);
sb.append(".");
sb.append(rightOfPoint);
return sb.toString();
}
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof SimpleBigDecimal))
{
return false;
}
SimpleBigDecimal other = (SimpleBigDecimal)o;
return ((bigInt.equals(other.bigInt)) && (scale == other.scale));
}
public int hashCode()
{
return bigInt.hashCode() ^ scale;
}
}