Number.java

/**
* Copyright 2010,2021 Nikolas S Boyd.
Permission is granted to copy this work provided this copyright statement is retained in all copies.

*/
package Hoot.Magnitudes;

import Hoot.Runtime.Functions.*;
import Hoot.Runtime.Faces.*;
import Hoot.Runtime.Values.*;
import Hoot.Runtime.Blocks.*;
import Smalltalk.Core.*;
import Smalltalk.Blocks.*;
import Smalltalk.Magnitudes.*;
import Hoot.Behaviors.*;
import Hoot.Behaviors.Nil;
import Hoot.Behaviors.Object;
import Hoot.Behaviors.True;
import Hoot.Behaviors.False;
import Hoot.Behaviors.Boolean;
import Hoot.Collections.*;
import Hoot.Collections.String;
import java.lang.Math;
import java.math.BigInteger;
import java.math.BigDecimal;
import Hoot.Runtime.Names.Primitive;
import Hoot.Runtime.Behaviors.Typified;
import Hoot.Geometry.Point;
import Hoot.Collections.Interval;
import Hoot.Exceptions.ZeroDivide;
import static Hoot.Magnitudes.SmallInteger.*;
import Smalltalk.Core.Subject;
import Smalltalk.Magnitudes.Scalar;
import Smalltalk.Magnitudes.Ordinal;
import Smalltalk.Magnitudes.Numeric;
import Smalltalk.Magnitudes.Floater;

public abstract class Number extends Magnitude implements Smalltalk.Magnitudes.Numeric, Smalltalk.Magnitudes.Floater
{

  public static Metaclass type() { return (Metaclass)Metaclass.$class; }
  @Override public Metaclass $class() { return (Metaclass)Metaclass.$class; }
  public static class Metaclass extends Magnitude.Metaclass implements Smalltalk.Magnitudes.Numeric.Metatype, Smalltalk.Magnitudes.Floater.Metatype
  {
    static final Number.Metaclass $class = new Number.Metaclass();
    public Metaclass() {
      this(Number.Metaclass.class);
    }

    public Metaclass(java.lang.Class aClass) {
      super(aClass);
    }

    @Override public java.lang.Class outerClass() { return Number.class; }


    /**
     * @return 
     */
    @Override public   Number zero()
    {
      java.lang.String exitID = "NumberMetatype>>zero";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Number)f0.exit(exitID, SmallInteger.Zero);
      });
    }

    /**
     * @return 
     */
    public   Number unity()
    {
      java.lang.String exitID = "NumberMetatype>>unity";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Number)f0.exit(exitID, SmallInteger.Unity);
      });
    }

    /**
     * @return 
     */
    public   Floater e()
    {
      java.lang.String exitID = "NumberMetatype>>e";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Floater)f0.exit(exitID, new Double(Math.E));
      });
    }

    /**
     * @return 
     */
    public   Floater pi()
    {
      java.lang.String exitID = "NumberMetatype>>pi";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Floater)f0.exit(exitID, new Double(Math.PI));
      });
    }

    /**
     * @return 
     */
    public   Boolean denormalized()
    {
      java.lang.String exitID = "NumberMetatype>>denormalized";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Boolean)f0.exit(exitID, False.literal());
      });
    }

    /**
     * @return 
     */
    public   Integer radix()
    {
      java.lang.String exitID = "NumberMetatype>>radix";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Integer)f0.exit(exitID, Duality);
      });
    }

    /**
     * @return 
     */
    public   Integer precision()
    {
      java.lang.String exitID = "NumberMetatype>>precision";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Integer)f0.exit(exitID, SmallInteger.from(32));
      });
    }

    /**
     * @return 
     */
    public   Integer emax()
    {
      java.lang.String exitID = "NumberMetatype>>emax";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Integer)f0.exit(exitID, SmallInteger.from(38));
      });
    }

    /**
     * @return 
     */
    public   Integer emin()
    {
      java.lang.String exitID = "NumberMetatype>>emin";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Integer)f0.exit(exitID, (Zero.minus(SmallInteger.from(45))));
      });
    }

    /**
     * @return 
     */
    public   Floater epsilon()
    {
      java.lang.String exitID = "NumberMetatype>>epsilon";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Floater)f0.exit(exitID, this.radix().raisedTo((Unity.minus(this.precision()))));
      });
    }

    /**
     * @return 
     */
    public   Floater fmax()
    {
      java.lang.String exitID = "NumberMetatype>>fmax";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Floater)f0.exit(exitID, new Float(Primitive.elementaryMaxFloat()));
      });
    }

    /**
     * @return 
     */
    public   Floater fmin()
    {
      java.lang.String exitID = "NumberMetatype>>fmin";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Floater)f0.exit(exitID, new Float(Primitive.elementaryMinFloat()));
      });
    }

    /**
     * @return 
     */
    public   Floater fminDenormalized()
    {
      java.lang.String exitID = "NumberMetatype>>fminDenormalized";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Floater)f0.exit(exitID, this.radix().raisedTo((this.emin().minus(this.precision()))));
      });
    }

    /**
     * @return 
     */
    public   Floater fminNormalized()
    {
      java.lang.String exitID = "NumberMetatype>>fminNormalized";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Floater)f0.exit(exitID, this.radix().raisedTo((this.emin().minus(Unity))));
      });
    }

    /**
     * @return 
     */
    public  <NumericType extends Number> NumericType coerce(final Number aNumber)
    {
      java.lang.String exitID = "NumberMetatype>>coerce";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      this.error(String.from("concrete derived metaclasses must override this method."));
      return (NumericType)f0.exit(exitID, null);
      });
    }

    /**
     * @return 
     */
    public  <NumericType extends Number> NumericType coerce(final Object aNumber)
    {
      java.lang.String exitID = "NumberMetatype>>coerce";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (NumericType)f0.exit(exitID, this.coerce(((Number)aNumber)));
      });
    }

    /**
     * @return 
     */
    public  <NumericType extends Number> NumericType zeroCoerced()
    {
      java.lang.String exitID = "NumberMetatype>>zeroCoerced";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (NumericType)f0.exit(exitID, ((NumericType)this.coerce(Zero)));
      });
    }

    /**
     * @return 
     */
    public  <NumericType extends Number> NumericType unityCoerced()
    {
      java.lang.String exitID = "NumberMetatype>>unityCoerced";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (NumericType)f0.exit(exitID, ((NumericType)this.coerce(Unity)));
      });
    }

    /**
     * @return 
     */
    protected   Number.Metaclass fromType(final Typified numberClass)
    {
      java.lang.String exitID = "NumberMetatype>>fromType";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Number.Metaclass)f0.exit(exitID, numberClass);
      });
    }
  }



  /**
   * 
   */
  protected    Number()
  {
    super();
    java.lang.String exitID = "Number>>Number";
    Frame f0 = new Frame(exitID);
  }

  /**
   * @return 
   */
  public   Boolean lessGeneral(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>lessGeneral";
    Frame f0 = new Frame(exitID);
    Number n = ((Number)aNumber);
    return (Boolean)(this.generality().lessThan(n.generality()));
  }

  /**
   * @return 
   */
  public  <NumericType extends Number> NumericType coerceTo(final Typified numberClass)
  {
    java.lang.String exitID = "Number>>coerceTo";
    Frame f0 = new Frame(exitID);
    return (NumericType)this.coerceTo(this.$class().fromType(numberClass));
  }

  /**
   * @return 
   */
  public  <NumericType extends Number> NumericType coerceTo(final Number.Metaclass numberClass)
  {
    java.lang.String exitID = "Number>>coerceTo";
    Frame f0 = new Frame(exitID);
    return (NumericType)numberClass.coerce(this);
  }

  /**
   * @return 
   */
  public abstract   Integer generality();

  /**
   * @return 
   */
  public   byte primitiveByte()
  {
    java.lang.String exitID = "Number>>primitiveByte";
    Frame f0 = new Frame(exitID);
    return (byte)this.elementaryNumber().byteValue();
  }

  /**
   * @return 
   */
  public   short primitiveShort()
  {
    java.lang.String exitID = "Number>>primitiveShort";
    Frame f0 = new Frame(exitID);
    return (short)this.elementaryNumber().shortValue();
  }

  /**
   * @return 
   */
  public   Character asCharacter()
  {
    java.lang.String exitID = "Number>>asCharacter";
    Frame f0 = new Frame(exitID);
    return (Character)Character.from(this.primitiveCharacter());
  }

  /**
   * @return 
   */
  public   char primitiveCharacter()
  {
    java.lang.String exitID = "Number>>primitiveCharacter";
    Frame f0 = new Frame(exitID);
    return (char)((char)this.elementaryNumber().intValue());
  }

  /**
   * @return 
   */
  public   SmallInteger asSmallInteger()
  {
    java.lang.String exitID = "Number>>asSmallInteger";
    Frame f0 = new Frame(exitID);
    return (SmallInteger)SmallInteger.from(this.primitiveInteger());
  }

  /**
   * @return 
   */
  public   int primitiveInteger()
  {
    java.lang.String exitID = "Number>>primitiveInteger";
    Frame f0 = new Frame(exitID);
    return (int)this.elementaryNumber().intValue();
  }

  /**
   * @return 
   */
  public   LongInteger asLongInteger()
  {
    java.lang.String exitID = "Number>>asLongInteger";
    Frame f0 = new Frame(exitID);
    return (LongInteger)new LongInteger(this.primitiveLong());
  }

  /**
   * @return 
   */
  public   long primitiveLong()
  {
    java.lang.String exitID = "Number>>primitiveLong";
    Frame f0 = new Frame(exitID);
    return (long)this.elementaryNumber().longValue();
  }

  /**
   * @return 
   */
  public   Float asFloatE()
  {
    java.lang.String exitID = "Number>>asFloatE";
    Frame f0 = new Frame(exitID);
    return (Float)this.asFloat();
  }

  /**
   * @return 
   */
  public   Float asFloat()
  {
    java.lang.String exitID = "Number>>asFloat";
    Frame f0 = new Frame(exitID);
    return (Float)Float.from(this.primitiveFloat());
  }

  /**
   * @return 
   */
  public   java.lang.Float primitiveFloat()
  {
    java.lang.String exitID = "Number>>primitiveFloat";
    Frame f0 = new Frame(exitID);
    return (java.lang.Float)this.elementaryNumber().floatValue();
  }

  /**
   * @return 
   */
  public   Double asFloatD()
  {
    java.lang.String exitID = "Number>>asFloatD";
    Frame f0 = new Frame(exitID);
    return (Double)Double.from(this.primitiveDouble());
  }

  /**
   * @return 
   */
  public   java.lang.Double primitiveDouble()
  {
    java.lang.String exitID = "Number>>primitiveDouble";
    Frame f0 = new Frame(exitID);
    return (java.lang.Double)this.elementaryNumber().doubleValue();
  }

  /**
   * @return 
   */
  public   Integer asInteger()
  {
    java.lang.String exitID = "Number>>asInteger";
    Frame f0 = new Frame(exitID);
    return (Integer)this.asLargeInteger().narrowGenerality();
  }

  /**
   * @return 
   */
  public   java.lang.Integer elementaryInteger()
  {
    java.lang.String exitID = "Number>>elementaryInteger";
    Frame f0 = new Frame(exitID);
    return (java.lang.Integer)this.elementaryNumber().intValue();
  }

  /**
   * @return 
   */
  public abstract   java.lang.Number elementaryNumber();

  /**
   * @return 
   */
  public   Rational asRational()
  {
    java.lang.String exitID = "Number>>asRational";
    Frame f0 = new Frame(exitID);
    return (Rational)this.asFraction();
  }

  /**
   * @return 
   */
  public   Fraction asFraction()
  {
    java.lang.String exitID = "Number>>asFraction";
    Frame f0 = new Frame(exitID);
    return (Fraction)new Fraction(this.asInteger());
  }

  /**
   * @return 
   */
  public   LargeInteger asLargeInteger()
  {
    java.lang.String exitID = "Number>>asLargeInteger";
    Frame f0 = new Frame(exitID);
    return (LargeInteger)LargeInteger.from(this.asBigInteger());
  }

  /**
   * @return 
   */
  public   BigInteger asBigInteger()
  {
    java.lang.String exitID = "Number>>asBigInteger";
    Frame f0 = new Frame(exitID);
    return (BigInteger)BigInteger.valueOf(this.primitiveLong());
  }

  /**
   * @return 
   */
  public   BigDecimal asDecimal()
  {
    java.lang.String exitID = "Number>>asDecimal";
    Frame f0 = new Frame(exitID);
    return (BigDecimal)new BigDecimal(this.primitiveLong());
  }

  /**
   * @return 
   */
  public   Fixed asFixedPoint(final Ordinal scale)
  {
    java.lang.String exitID = "Number>>asFixedPoint";
    Frame f0 = new Frame(exitID);
    return (Fixed)this.asFraction().scaledAt(((Integer)scale));
  }

  /**
   * @return 
   */
  public   Fixed asScaledDecimal(final Ordinal scale)
  {
    java.lang.String exitID = "Number>>asScaledDecimal";
    Frame f0 = new Frame(exitID);
    return (Fixed)this.asFraction().scaledAt(((Integer)scale));
  }

  /**
   * @return 
   */
  public   Point asPoint()
  {
    java.lang.String exitID = "Number>>asPoint";
    Frame f0 = new Frame(exitID);
    return (Point)(this.at(this));
  }

  /**
   * @return 
   */
  public   Number minus(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>minus";
    Frame f0 = new Frame(exitID);
    return (Number)(((Number)aNumber).negated().plus(this));
  }

  /**
   * @return 
   */
  public   Number plus(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>plus";
    Frame f0 = new Frame(exitID);
    return (Number)(((Number)aNumber).plus(this));
  }

  /**
   * @return 
   */
  public   Number times(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>times";
    Frame f0 = new Frame(exitID);
    return (Number)(((Number)aNumber).times(this));
  }

  /**
   * @return 
   */
  @Override public   Number divideWith(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>divideWith";
    Frame f0 = new Frame(exitID);
    return (Number)(this.divideWith(((Number)aNumber)));
  }

  /**
   * @return 
   */
  public   Integer truncateWith(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>truncateWith";
    Frame f0 = new Frame(exitID);
    return (Integer)(this.divideWith(((Number)aNumber))).floor();
  }

  /**
   * @return 
   */
  public   Number remainderFrom(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>remainderFrom";
    Frame f0 = new Frame(exitID);
    return (Number)(this.minus(this.truncateWith(((Number)aNumber)).times(((Number)aNumber))));
  }

  /**
   * @return 
   */
  public   Number modulo(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>modulo";
    Frame f0 = new Frame(exitID);
    return (Number)(this.remainderFrom(((Number)aNumber)));
  }

  /**
   * @return 
   */
  public   Number zeroDivide()
  {
    java.lang.String exitID = "Number>>zeroDivide";
    Frame f0 = new Frame(exitID);
    ZeroDivide.type().dividend(this);
    return (Number)this;
  }

  /**
   * @return 
   */
  public   Point at(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>at";
    Frame f0 = new Frame(exitID);
    return (Point)new Point().x_y(this, ((Number)aNumber));
  }

  /**
   * @return 
   */
  public   Number raisedTo(final Ordinal power)
  {
    java.lang.String exitID = "Number>>raisedTo";
    Frame f0 = new Frame(exitID);
    return (Number)this.raisedTo(Double.from(((Number)power).primitiveDouble()));
  }

  /**
   * @return 
   */
  public   Number raisedTo(final Numeric power)
  {
    java.lang.String exitID = "Number>>raisedTo";
    Frame f0 = new Frame(exitID);
    return (Number)this.raisedTo(Double.from(((Number)power).primitiveDouble()));
  }

  /**
   * @return 
   */
  public   Number raisedTo(final Double power)
  {
    java.lang.String exitID = "Number>>raisedTo";
    Frame f0 = new Frame(exitID);
    return (Number)this.asFloatD().raisedTo(power);
  }

  /**
   * @return 
   */
  public   Number abs()
  {
    java.lang.String exitID = "Number>>abs";
    Frame f0 = new Frame(exitID);
    return (Number)(this.lessThan(this.$class().zero())).ifTrue_ifFalse(Closure.with(f2 -> {
      return this.negated();
    }, ""), Closure.with(f2 -> {
      return this;
    }, ""));
  }

  /**
   * @return 
   */
  public   Rational fractionPart()
  {
    java.lang.String exitID = "Number>>fractionPart";
    Frame f0 = new Frame(exitID);
    return (Rational)(this.minus(this.truncated())).asRational();
  }

  /**
   * @return 
   */
  public   Integer integerPart()
  {
    java.lang.String exitID = "Number>>integerPart";
    Frame f0 = new Frame(exitID);
    return (Integer)this.truncated();
  }

  /**
   * @return 
   */
  public   Number negated()
  {
    java.lang.String exitID = "Number>>negated";
    Frame f0 = new Frame(exitID);
    return (Number)(this.$class().zero().minus(this));
  }

  /**
   * @return 
   */
  public   Number reciprocal()
  {
    java.lang.String exitID = "Number>>reciprocal";
    Frame f0 = new Frame(exitID);
    return (Number)(this.$class().unity().divideWith(this));
  }

  /**
   * @return 
   */
  public   Number squared()
  {
    java.lang.String exitID = "Number>>squared";
    Frame f0 = new Frame(exitID);
    return (Number)((Number)(this.times(this)));
  }

  /**
   * @return 
   */
  public   Integer quo(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>quo";
    Frame f0 = new Frame(exitID);
    return (Integer)(this.divideWith(aNumber)).truncated();
  }

  /**
   * @return 
   */
  public   Number rem(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>rem";
    Frame f0 = new Frame(exitID);
    return (Number)(this.minus(this.truncatedTo(aNumber)));
  }

  /**
   * @return 
   */
  public   Integer sign()
  {
    java.lang.String exitID = "Number>>sign";
    Frame f0 = new Frame(exitID);
    if (this.strictlyPositive().asPrimitive()) {
      return Unity;
    };
    if (this.negative().asPrimitive()) {
      return Negativity;
    };
    return (Integer)Zero;
  }

  /**
   * @return 
   */
  public   Number sqrt()
  {
    java.lang.String exitID = "Number>>sqrt";
    Frame f0 = new Frame(exitID);
    java.lang.Double rootD = Math.sqrt(this.primitiveDouble());

    long rootL = rootD.longValue();
    if ((rootL == rootD)) {
      int rootI = ((int)rootL);
      return (Boolean.primitiveValue((rootI == rootL)) ? new SmallInteger(rootI) : new LongInteger(rootL));
    };

    java.lang.Float rootF = rootD.floatValue();
    return (Number)(Boolean.primitiveValue((rootF.doubleValue() == rootD)) ? new Float(rootF) : new Double(rootD));
  }

  /**
   * @return 
   */
  public   Floater cos()
  {
    java.lang.String exitID = "Number>>cos";
    Frame f0 = new Frame(exitID);
    return (Floater)new Double(Math.cos(this.primitiveFloat()));
  }

  /**
   * @return 
   */
  public   Floater arcCos()
  {
    java.lang.String exitID = "Number>>arcCos";
    Frame f0 = new Frame(exitID);
    return (Floater)new Double(Math.acos(this.primitiveFloat()));
  }

  /**
   * @return 
   */
  public   Floater arcSin()
  {
    java.lang.String exitID = "Number>>arcSin";
    Frame f0 = new Frame(exitID);
    return (Floater)new Double(Math.asin(this.primitiveFloat()));
  }

  /**
   * @return 
   */
  public   Floater arcTan()
  {
    java.lang.String exitID = "Number>>arcTan";
    Frame f0 = new Frame(exitID);
    return (Floater)new Double(Math.atan(this.primitiveFloat()));
  }

  /**
   * @return 
   */
  public   Floater exp()
  {
    java.lang.String exitID = "Number>>exp";
    Frame f0 = new Frame(exitID);
    return (Floater)new Double(Math.exp(this.primitiveFloat()));
  }

  /**
   * @return 
   */
  public   Double degreesToRadians()
  {
    java.lang.String exitID = "Number>>degreesToRadians";
    Frame f0 = new Frame(exitID);
    return (Double)new Double((this.primitiveDouble() * Primitive.radiansPerDegree()));
  }

  /**
   * @return 
   */
  public   Double radiansToDegrees()
  {
    java.lang.String exitID = "Number>>radiansToDegrees";
    Frame f0 = new Frame(exitID);
    return (Double)new Double((this.primitiveDouble() * Primitive.degreesPerRadian()));
  }

  /**
   * @return 
   */
  public   Double ln()
  {
    java.lang.String exitID = "Number>>ln";
    Frame f0 = new Frame(exitID);
    return (Double)new Double(Math.log(this.primitiveFloat()));
  }

  /**
   * @return 
   */
  public   Number log(final Numeric radix)
  {
    java.lang.String exitID = "Number>>log";
    Frame f0 = new Frame(exitID);
    return (Number)(this.ln().divideWith(((Number)radix).ln()));
  }

  /**
   * @return 
   */
  public   Integer floorLog(final Numeric radix)
  {
    java.lang.String exitID = "Number>>floorLog";
    Frame f0 = new Frame(exitID);
    return (Integer)this.log(((Number)radix).asFloat()).floor();
  }

  /**
   * @return 
   */
  public   Double sin()
  {
    java.lang.String exitID = "Number>>sin";
    Frame f0 = new Frame(exitID);
    return (Double)new Double(Math.sin(this.primitiveFloat()));
  }

  /**
   * @return 
   */
  public   Double tan()
  {
    java.lang.String exitID = "Number>>tan";
    Frame f0 = new Frame(exitID);
    return (Double)new Double(Math.tan(this.primitiveFloat()));
  }

  /**
   * @return 
   */
  public abstract   Integer floor();

  /**
   * @return 
   */
  public abstract   Integer ceiling();

  /**
   * @return 
   */
  public   Integer truncated()
  {
    java.lang.String exitID = "Number>>truncated";
    Frame f0 = new Frame(exitID);
    return (Integer)this.negative().ifTrue_ifFalse(Closure.with(f2 -> {
      return this.ceiling();
    }, ""), Closure.with(f2 -> {
      return this.floor();
    }, ""));
  }

  /**
   * @return 
   */
  public   Number truncatedTo(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>truncatedTo";
    Frame f0 = new Frame(exitID);
    return (Number)(this.quo(aNumber).times(aNumber));
  }

  /**
   * @return 
   */
  public   Integer rounded()
  {
    java.lang.String exitID = "Number>>rounded";
    Frame f0 = new Frame(exitID);
    return (Integer)(this.plus((this.sign().divideWith(Duality)))).truncated();
  }

  /**
   * @return 
   */
  public   Number roundTo(final Numeric aNumber)
  {
    java.lang.String exitID = "Number>>roundTo";
    Frame f0 = new Frame(exitID);
    return (Number)((this.divideWith(aNumber)).rounded().times(aNumber));
  }

  /**
   * @return 
   */
  public   Number faultIfZero()
  {
    java.lang.String exitID = "Number>>faultIfZero";
    Frame f0 = new Frame(exitID);
    this.isZero().ifTrue(Closure.with(f2 -> {
      this.zeroDivide();
    }, ""));
    return (Number)this;
  }

  /**
   * @return 
   */
  public   Boolean isZero()
  {
    java.lang.String exitID = "Number>>isZero";
    Frame f0 = new Frame(exitID);
    return (Boolean)(((Numeric)this.$class().zero()).equals(this));
  }

  /**
   * @return 
   */
  public   Boolean negative()
  {
    java.lang.String exitID = "Number>>negative";
    Frame f0 = new Frame(exitID);
    return (Boolean)Boolean.from((this.lessThan(this.$class().zero())));
  }

  /**
   * @return 
   */
  public   Boolean positive()
  {
    java.lang.String exitID = "Number>>positive";
    Frame f0 = new Frame(exitID);
    return (Boolean)Boolean.from((this.notLess(this.$class().zero())));
  }

  /**
   * @return 
   */
  public   Boolean strictlyPositive()
  {
    java.lang.String exitID = "Number>>strictlyPositive";
    Frame f0 = new Frame(exitID);
    return (Boolean)Boolean.from((this.moreThan(this.$class().zero())));
  }

  /**
   * @return 
   */
  public   Interval to(final Ordinal aNumber)
  {
    java.lang.String exitID = "Number>>to";
    Frame f0 = new Frame(exitID);
    return (Interval)Interval.type().from_to(this.asInteger(), aNumber);
  }

  /**
   * @return 
   */
  public   Interval to_by(final Ordinal aNumber, final Ordinal delta)
  {
    java.lang.String exitID = "Number>>to_by";
    Frame f0 = new Frame(exitID);
    return (Interval)Interval.type().from_to_by(this.asInteger(), aNumber, delta);
  }

  /**
   * @return 
   */
  public   Number to_do(final Ordinal aNumber, final MonadicValuable aBlock)
  {
    java.lang.String exitID = "Number>>to_do";
    Frame f0 = new Frame(exitID);
    this.to_by_do(aNumber, Unity, aBlock);
    return (Number)this;
  }

  /**
   * @return 
   */
  public   Number to_by_do(final Ordinal aNumber, final Ordinal delta, final MonadicValuable aBlock)
  {
    java.lang.String exitID = "Number>>to_by_do";
    Frame f0 = new Frame(exitID);
    int index = this.primitiveInteger();
    if ((delta.intValue() > 0)) {
      while((index <= aNumber.intValue())) {
        aBlock.value(SmallInteger.from(index));
        index += delta.intValue();
      };
    }
    else {
      while((aNumber.intValue() <= index)) {
        aBlock.value(SmallInteger.from(index));
        index += delta.intValue();
      };
    };
    return (Number)this;
  }
}