PsyBigInteger.java
package coneforest.psylla.core;
import coneforest.psylla.runtime.*;
import java.math.BigInteger;
/**
* The representation of {@code biginteger}, arbitrary precision integer.
*/
@Type("biginteger")
public final class PsyBigInteger
implements PsyIntegral
{
private final BigInteger value;
/**
* Constructs a new {@code biginteger} for the given value.
*
* @param value the value.
*/
public PsyBigInteger(final BigInteger value)
{
this.value=value;
}
@Override
public boolean isZero()
{
return false;
}
@Override
public int intValue()
{
return value.intValue();
}
@Override
public long longValue()
{
return value.longValue();
}
@Override
public double doubleValue()
{
return value.doubleValue();
}
@Override
public BigInteger bigIntegerValue()
{
return value;
}
@Override
public PsyBigInteger psyBitShift(final PsyInteger oShift)
{
return new PsyBigInteger(value.shiftLeft(oShift.intValue()));
}
@Override
public PsyBoolean psyTestBit(final PsyInteger oBit)
{
return PsyBoolean.of(value.testBit(oBit.intValue()));
}
@Override
public PsyIntegral psySetBit(final PsyInteger oBit)
{
return PsyIntegral.of(value.setBit(oBit.intValue()));
}
@Override
public PsyIntegral psyFlipBit(final PsyInteger oBit)
throws PsyRangeCheckException
{
try
{
return PsyIntegral.of(value.flipBit(oBit.intValue()));
}
catch(final ArithmeticException ex)
{
throw new PsyRangeCheckException();
}
}
@Override
public PsyIntegral psyClearBit(final PsyInteger oBit)
{
return PsyIntegral.of(value.clearBit(oBit.intValue()));
}
@Override
public PsyIntegral psyOr(final PsyIntegral oIntegral)
{
return PsyIntegral.of(value.or(oIntegral.bigIntegerValue()));
}
@Override
public PsyIntegral psyAnd(final PsyIntegral oIntegral)
{
return PsyIntegral.of(value.and(oIntegral.bigIntegerValue()));
}
@Override
public PsyIntegral psyXor(final PsyIntegral oIntegral)
{
return PsyIntegral.of(value.xor(oIntegral.bigIntegerValue()));
}
@Override
public PsyBigInteger psyNot()
{
return new PsyBigInteger(value.not());
}
@Override
public PsyIntegral psyAbs()
{
return PsyIntegral.of(value.abs());
}
@Override
public PsyIntegral psyIdiv(final PsyRational oRational)
throws PsyUndefinedResultException
{
return switch(oRational)
{
case PsyInteger oInteger when oInteger==PsyInteger.ZERO->
throw new PsyUndefinedResultException();
case PsyInteger oInteger->PsyIntegral.of(
value.divide(BigInteger.valueOf(oInteger.longValue())));
case PsyBigInteger oBigInteger->
PsyIntegral.of(value.divide(oBigInteger.value));
default->((PsyIntegral)psyMul(oRational.psyDenominator()))
.psyIdiv(oRational.psyNumerator());
};
}
@Override
public PsyIntegral psyMod(final PsyRational oRational)
throws PsyUndefinedResultException, PsyRangeCheckException
{
return switch(oRational)
{
case PsyIntegral oIntegral when oIntegral==PsyInteger.ZERO->
throw new PsyUndefinedResultException();
case PsyIntegral oIntegral->
{
try
{
yield PsyIntegral.of(value.mod(oIntegral.bigIntegerValue()));
}
catch(final ArithmeticException ex)
{
throw new PsyRangeCheckException();
}
}
default->((PsyIntegral)psyMul(oRational.psyDenominator()))
.psyMod(oRational.psyNumerator());
};
}
@Override
public PsyRational psyGCD(final PsyRational oRational)
{
return switch(oRational)
{
case PsyIntegral oIntegral when oIntegral==PsyInteger.ZERO->
psyAbs();
case PsyIntegral oIntegral->
PsyIntegral.of(value.gcd(oIntegral.bigIntegerValue()));
default->oRational.psyGCD(this);
};
}
@Override
public PsyRealNumeric psyMul(final PsyRealNumeric oRealNumeric)
{
return switch(oRealNumeric)
{
case PsyIntegral oIntegral->
PsyIntegral.of(value.multiply(oIntegral.bigIntegerValue()));
case PsyRational oRational->PsyRational.of((PsyIntegral)psyMul(oRational.psyNumerator()),
oRational.psyDenominator());
case PsyReal oReal->new PsyReal(doubleValue()*oReal.doubleValue());
};
}
@Override
public PsyRealNumeric psyDiv(final PsyRealNumeric oRealNumeric)
throws PsyUndefinedResultException
{
return switch(oRealNumeric)
{
case PsyIntegral oIntegral->
PsyRational.of(psyNumerator(), (PsyIntegral)psyDenominator().psyMul(oIntegral));
case PsyRational oRational->PsyRational.of(
(PsyIntegral)psyNumerator().psyMul(oRational.psyDenominator()),
(PsyIntegral)psyDenominator().psyMul(oRational.psyNumerator()));
case PsyReal oReal->new PsyReal(doubleValue()*oReal.doubleValue());
};
}
@Override
public PsyRealNumeric psyAdd(final PsyRealNumeric oRealNumeric)
{
return switch(oRealNumeric)
{
case PsyIntegral oIntegral->
PsyIntegral.of(value.add(oIntegral.bigIntegerValue()));
case PsyRational oRational->
PsyRational.of((PsyIntegral)psyMul(oRational.psyDenominator())
.psyAdd(oRational.psyNumerator()),
oRational.psyDenominator());
case PsyReal oReal->new PsyReal(doubleValue()+oReal.doubleValue());
};
}
@Override
public PsyRealNumeric psySub(final PsyRealNumeric oRealNumeric)
{
return switch(oRealNumeric)
{
case PsyIntegral oIntegral->
PsyIntegral.of(value.subtract(oIntegral.bigIntegerValue()));
case PsyRational oRational->
PsyRational.of((PsyIntegral)psyMul(
oRational.psyDenominator()).psySub(oRational.psyNumerator()),
oRational.psyDenominator());
case PsyReal oReal->new PsyReal(doubleValue()-oReal.doubleValue());
};
}
@Override
public PsyIntegral psyNeg()
{
return PsyIntegral.of(value.negate());
}
@Override
public PsyInteger psySignum()
{
return PsyInteger.of(value.signum());
}
@Override
public int compareTo(final PsyRealNumeric oRealNumeric)
{
return switch(oRealNumeric)
{
case PsyIntegral oIntegral->
value.compareTo(oIntegral.bigIntegerValue());
case PsyRational oRational->
psyMul(oRational.psyDenominator()).compareTo(oRational.psyNumerator());
case PsyReal oReal->
Double.compare(doubleValue(), oReal.doubleValue());
};
}
@Override
public String toSyntaxString()
{
return String.valueOf(value);
}
@Override
public boolean equals(final Object obj)
{
return obj instanceof PsyBigInteger oBigInteger
&& value.equals(oBigInteger.value);
}
@Override
public int hashCode()
{
return value.hashCode();
}
}