Skip to content

Commit

Permalink
Introduce the "torational" operator
Browse files Browse the repository at this point in the history
  • Loading branch information
urbic committed May 8, 2024
1 parent 483c05e commit 6a80474
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,6 @@ public PsyIntegral psyToIntegral()
return null;
}

@Override
public PsyInteger psyCmp(final PsyRealNumeric oRealNumeric)
{
// TODO
System.err.println("PsyBigFraction::psyCmp");
return null;
}

@Override
public PsyReal psyRound()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package coneforest.psylla.core;

import coneforest.psylla.*;

@Type("convertabletorational")
public interface PsyConvertableToRational
extends PsyObject
{
public PsyRational psyToRational()
throws PsyErrorException;

/**
* Context action of the {@code torational} operator.
*/
@OperatorType("torational")
public static final ContextAction PSY_TORATIONAL
=ContextAction.<PsyConvertableToRational>ofFunction(PsyConvertableToRational::psyToRational);
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,10 @@ public PsyIntegral psyToIntegral()
return null;
}

@Override
public PsyInteger psyCmp(final PsyRealNumeric oRealNumeric)
{
// TODO
return null;
}

@Override
public PsyReal psyRound()
{
return new PsyReal(Math.round((double)numerator/(double)denominator));
return new PsyReal(Math.round(doubleValue()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public sealed interface PsyRational
{
public BigInteger bigIntegerValue();

default public PsyRational rationalValue()
{
return this;
}

/**
* Returns an {@code integral} numerator of this fraction.
*
Expand All @@ -30,6 +35,12 @@ public sealed interface PsyRational
*/
public PsyIntegral psyDenominator();

@Override
default public PsyRational psyToRational()
{
return this;
}

@Override
default public PsyRational psyNeg()
{
Expand Down Expand Up @@ -152,6 +163,7 @@ default public int cmp(final PsyRealNumeric oNumeric)
if(oNumeric instanceof PsyRational oRational)
return psyNumerator().psyMul(oRational.psyDenominator())
.cmp(psyDenominator().psyMul(oRational.psyNumerator()));
// TODO
return Double.compare(doubleValue(), oNumeric.doubleValue());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import coneforest.psylla.*;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
* The representation of {@code real}.
Expand Down Expand Up @@ -48,6 +49,40 @@ public double doubleValue()
return value;
}

@Override
public PsyRational rationalValue()
throws PsyUndefinedResultException
{
if(value==0.D||value==-0.D)
return PsyInteger.ZERO;
if(Double.isNaN(value)||Double.isInfinite(value))
throw new PsyUndefinedResultException();

final long bits=Double.doubleToLongBits(value);
final long mantissa=bits&0x000FFFFFFFFFFFFFL;
final int exponent=(int)((bits&0x7FF0000000000000L)>>52);

if(exponent==0)
return (PsyRational)PsyInteger
.of((bits&0x8000000000000000L)==0L? mantissa: -mantissa)
.psyDiv(new PsyBigInteger(BigInteger.ZERO.flipBit(-51-Double.MAX_EXPONENT)));

final int pow=exponent-Double.MAX_EXPONENT;

PsyRational retval=(PsyRational)PsyInteger.of(mantissa)
.psyDiv(PsyInteger.of(0x10000000000000L))
.psyAdd(PsyInteger.ONE);
if((bits&0x8000000000000000L)!=0L)
retval=retval.psyNeg();
return (PsyRational)(pow>=0?
retval.psyMul((pow<63)?
PsyInteger.of(1L<<pow):
new PsyBigInteger(BigInteger.ZERO.flipBit(pow))):
retval.psyDiv((-pow<63)?
PsyInteger.of(1L<<-pow):
new PsyBigInteger(BigInteger.ZERO.flipBit(-pow))));
}

@Override
public PsyReal psyNeg()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public sealed interface PsyRealNumeric
PsyNumeric,
PsyConvertableToInteger,
PsyConvertableToIntegral,
PsyConvertableToRational,
PsyConvertableToReal,
PsyScalar<PsyRealNumeric>
permits
Expand All @@ -24,6 +25,16 @@ public sealed interface PsyRealNumeric

public double doubleValue();

public PsyRational rationalValue()
throws PsyUndefinedResultException;

@Override
default public PsyRational psyToRational()
throws PsyUndefinedResultException
{
return rationalValue();
}

@Override
default public double realValue()
{
Expand Down

0 comments on commit 6a80474

Please sign in to comment.