"Abstraction of [[numeric|Numeric]] types with a natural 
 [[total order|Comparable]], including the built-in numeric 
 types [[Integer]] and [[Float]].
 
 A `Number` has a well-defined [[magnitude]] together with a 
 [[sign]] of type [[Integer]], defined for any instance `x`
 as follows:
 
 - if `x==0` then `x.sign==0` and `x.magnitude==0`,
 - if `x>0` then `x.sign==1` and `x.magnitude==x`, or
 - if `x<0` then `x.sign==-1` and `x.magnitude==-x`,
 
 where `0` is the additive identity of the numeric type.
 
 Not every value commonly considered to be a \"number\" is
 a `Number`. For example, complex numbers aren't `Number`s
 since they don't have a total order."
see (`class Integer`, `class Float`)
by ("Gavin")
tagged("Numbers")
shared interface Number<Other> of Other
        satisfies Numeric<Other> & 
                  Comparable<Other>
        given Other satisfies Number<Other> {
    
    "The magnitude of this number, defined for any instance 
     `x` as:
     
     - `-x` if `x<0`, or 
     - `x` otherwise,
     
     where `0` is the additive identity. Hence:
     
     - `x.magnitude >= 0` for any `x`, and
     - `x.magnitude == 0` if and only if `x==0`."
    aliased("absolute")
    shared default Other magnitude
            => negative then negated else this of Other;
    
    "The sign of this number: 
     
     - `1` if the number is [[positive]], 
     - `-1` if it is [[negative]], or 
     - `0` if it is the additive identity.
     
     Must satisfy:
     
         x.magnitude.timesInteger(x.sign) == x"
    shared default Integer sign {
        if (positive) {
            return 1;
        }
        else if (negative) {
            return -1;
        }
        else {
            return 0;
        }
    }
    
    "Determine if the number is strictly positive, that is, 
     if `this>0`, where `0` is the additive identity."
    shared formal Boolean positive;
    
    "Determine if the number is strictly negative, that is, 
     if `this<0`, where `0` is the additive identity."
    shared formal Boolean negative;
    
    "The fractional part of this number, after truncation of 
     the integral part. For [[Integral]] numeric types, the 
     fractional part is always zero."
    shared formal Other fractionalPart;
    
    "The integral value of the number after truncation of 
     the fractional part. For [[Integral]] numeric types, 
     the integral value of a number is the number itself."
    shared formal Other wholePart;
    
    "The result of multiplying this number by the given 
     [[Integer]]."
    shared formal Other timesInteger(Integer integer);
    
    "The result of adding this number to the given 
     [[Integer]]."
    shared formal Other plusInteger(Integer integer);
    
    "The result of raising this number to the given 
     non-negative [[Integer]] power. For a negative power,
     the behavior is implementation-dependent."
    throws (`class AssertionError`, 
            "if the exponent is a negative power and this is 
             an integral numeric type")
    shared formal Other powerOfInteger(Integer integer);
    
}