Multi precision integer and rational number using gmp lib

Introduced classes

class BigInt

gmp :: BigInt

Multi precision Integer numbers.
class Ratio

gmp :: Ratio

Multi precision Rational numbers.

Redefined classes

redef enum Float

gmp :: gmp $ Float

Native floating point numbers.
redef enum Int

gmp :: gmp $ Int

Native integer numbers.
redef interface Numeric

gmp :: gmp $ Numeric

A numeric value supporting mathematical operations
redef abstract class Text

gmp :: gmp $ Text

High-level abstraction for all text representations

All class definitions

class BigInt

gmp $ BigInt

Multi precision Integer numbers.
redef enum Float

gmp :: gmp $ Float

Native floating point numbers.
redef enum Int

gmp :: gmp $ Int

Native integer numbers.
redef interface Numeric

gmp :: gmp $ Numeric

A numeric value supporting mathematical operations
class Ratio

gmp $ Ratio

Multi precision Rational numbers.
redef abstract class Text

gmp :: gmp $ Text

High-level abstraction for all text representations
package_diagram gmp::gmp gmp gmp::native_gmp native_gmp gmp::gmp->gmp::native_gmp core core gmp::native_gmp->core ...core ... ...core->core a_star-m a_star-m a_star-m->gmp::gmp

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module array

core :: array

This module introduces the standard array structure.
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module math

core :: math

Mathematical operations
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module native_gmp

gmp :: native_gmp

Low-level GMP features

Children

module a_star-m

a_star-m

# Multi precision integer and rational number using gmp lib
module gmp

private import native_gmp

redef class Numeric

    # The BigInt equivalent of `self`
    fun to_bi: BigInt do return self.to_i.to_bi

    # The Ratio equivalent of `self`
    fun to_r: Ratio do return self.to_f.to_r

end

redef class Text

    # Is `self` a well-formed BigInt (i.e. parsable via `to_bi`)
    #
    #     assert "123".is_bi
    #     assert "-123".is_bi
    #     assert not "0b1011".is_bi
    #     assert not "123u8".is_bi
    #     assert not "Not a BigInt".is_bi
    fun is_bi: Bool do
        var pre = prefix("-")
        if pre != null then
            return pre.text_after.is_dec
        else
            return is_dec
        end
    end

    # Is `self` a well-formed Ratio (i.e. parsable via `to_r`)
    #
    #     assert "123".is_r
    #     assert "-123".is_r
    #     assert "1/2".is_r
    #     assert "-1/2".is_r
    #     assert not "-1/-2".is_r
    #     assert not "0b1011".is_r
    #     assert not "123u8".is_r
    #     assert not "Not an Ratio".is_r
    fun is_r: Bool do
        var frac = split_once_on('/')
        if frac.length == 2 then
            return frac[0].is_bi and frac[1].is_dec
        else
            return is_bi
        end
    end

    # If `self` contains a BigInt, return the corresponding BigInt
    #
    #     assert("123".to_bi == 123.to_bi)
    #     assert("-123".to_bi == -123.to_bi)
    fun to_bi: BigInt do
        assert is_bi
        var tmp = new NativeMPZ
        tmp.set_str(self.to_cstring, 10i32)
        return new BigInt(tmp)
    end

    # If `self` contains a Ratio, return the corresponding Ratio
    #
    #     assert("123".to_r == 123.to_r)
    #     assert("-123".to_r == -123.to_r)
    #     assert("1/2".to_r == 0.5.to_r)
    #     assert("-1/2".to_r == -0.5.to_r)
    fun to_r: Ratio do
        assert is_r
        var tmp = new NativeMPQ
        tmp.set_str self.to_cstring
        return new Ratio(tmp)
    end
end

redef class Float
    redef fun to_bi do
        var tmp = new NativeMPZ
        tmp.set_d self
        return new BigInt(tmp)
    end

    redef fun to_r do
        var tmp = new NativeMPQ
        tmp.set_d self
        return new Ratio(tmp)
    end
end

redef class Int
    redef fun to_bi do
        var tmp = new NativeMPZ
        tmp.set_si self
        return new BigInt(tmp)
    end

    redef fun to_r do
        var tmp = new NativeMPQ
        tmp.set_si(self, 1)
        return new Ratio(tmp)
    end
end

# Multi precision Integer numbers.
class BigInt
    super Discrete
    super Numeric
    super FinalizableOnce

    redef type OTHER: BigInt

    private var val: NativeMPZ

    redef fun successor(i) do return self + i.to_bi
    redef fun predecessor(i) do return self - i.to_bi

    redef fun hash do return self.to_i

    redef fun <=>(i) do
        var res = val.cmp(i.val)
        if (res) < 0 then
            return -1
        else if (res) > 0 then
            return 1
        else
            return 0
        end
    end

    redef fun ==(i) do return i isa BigInt and (self <=> i) == 0
    redef fun <=(i) do return (self <=> i) <= 0
    redef fun <(i) do return (self <=> i) < 0
    redef fun >=(i) do return (self <=> i) >= 0
    redef fun >(i) do return (self <=> i) > 0


    #     assert(2.to_bi + 2.to_bi == 4.to_bi)
    redef fun +(i) do
        var res = new NativeMPZ
        val.add(res, i.val)
        return new BigInt(res)
    end

    #     assert(-(2.to_bi) == (-2).to_bi)
    redef fun - do
        var res = new NativeMPZ
        val.neg res
        return new BigInt(res)
    end

    #     assert(2.to_bi - 2.to_bi == 0.to_bi)
    redef fun -(i) do
        var res = new NativeMPZ
        val.sub(res, i.val)
        return new BigInt(res)
    end

    #     assert(2.to_bi * 2.to_bi == 4.to_bi)
    redef fun *(i) do
        var res = new NativeMPZ
        val.mul(res, i.val)
        return new BigInt(res)
    end

    #     assert(3.to_bi / 2.to_bi == 1.to_bi)
    redef fun /(i) do
        var res = new NativeMPZ
        val.tdiv_q(res, i.val)
        return new BigInt(res)
    end

    # Modulo of `self` with `i`.
    #
    # Finds the remainder of the division of `self` by `i`.
    #
    #     assert(5.to_bi % 2.to_bi == 1.to_bi)
    fun %(i: BigInt): BigInt do
        var res = new NativeMPZ
        val.mod(res, i.val)
        return new BigInt(res)
    end

    # Returns `self` raised to the power of `e`.
    #
    #     assert(3.to_bi ** 2 == 9.to_bi)
    fun **(e: Int): BigInt do
        var res = new NativeMPZ
        var pow = new UInt64
        pow.set_si e
        val.pow_ui(res, pow)
        pow.free
        return new BigInt(res)
    end

    # The absolute value of `self`.
    #
    #     assert((-3).to_bi.abs == 3.to_bi)
    fun abs: BigInt do
        var res = new NativeMPZ
        val.abs res
        return new BigInt(res)
    end

    # Returns the greatest common divisor of `self` and `i`
    #
    #     assert(15.to_bi.gcd(10.to_bi) == 5.to_bi)
    fun gcd(i: BigInt): BigInt do
        var res = new NativeMPZ
        val.gcd(res, i.val)
        return new BigInt(res)
    end

    # Determine if `self` is a prime number.
    # Return 2 if `self` is prime, return 1 if `self` is probably prime and
    # return 0 if `self` is definitely not a prime number.
    #
    # This function begins by trying some divisions with small number to find if
    # there is other factors then `self` and one. After that, it uses the
    # Miller-Rabin probabilistic primality tests. The probability of a non-prime
    # being identified as probably prime with that test is less than
    # `4^(-reps)`. It is recommended to use a `reps` value between 15 and 50.
    #
    #     assert((0x10001).to_bi.probab_prime(15) == 2)
    fun probab_prime(reps: Int): Int do
        return val.probab_prime_p(reps.to_i32)
    end

    # Return the next prime number greater than `self`.
    # This fonction uses a probabilistic algorithm.
    #
    #     assert(11.to_bi.next_prime == 13.to_bi)
    fun next_prime: BigInt do
        var res = new NativeMPZ
        val.nextprime res
        return new BigInt(res)
    end

    #     assert(11.to_bi.zero == 0.to_bi)
    redef fun zero do return new BigInt(new NativeMPZ)

    #     assert(11.to_bi.value_of(4) == 4.to_bi)
    redef fun value_of(i) do return i.to_bi

    #     assert(11.to_bi.to_i == 11)
    redef fun to_i do return val.get_si

    #     assert(11.to_bi.to_f == 11.0)
    redef fun to_f do return val.get_d

    #     assert(11.to_bi.to_s == "11")
    redef fun to_s do
        var cstr = val.get_str(10.to_i32)
        var str = cstr.to_s
        cstr.free
        return str
    end

    redef fun to_bi do return self

    #     assert(123.to_bi.to_r == 123.to_r)
    redef fun to_r do
        var tmp = new NativeMPQ
        tmp.set_z val
        return new Ratio(tmp)
    end

    #     assert(3.to_bi.distance(6.to_bi) == -3)
    redef fun distance(i) do return (self - i).to_i

    redef fun finalize_once do val.finalize
end

# Multi precision Rational numbers.
#
#     assert((0.2 + 0.1) == 0.30000000000000004)
#     assert(("1/5".to_r + "1/10".to_r) == "3/10".to_r)
class Ratio
    super Numeric
    super FinalizableOnce

    redef type OTHER: Ratio

    private var val: NativeMPQ

    redef fun hash do return self.to_i

    redef fun <=>(r) do
        var res = val.cmp(r.val)
        if (res) < 0 then
            return -1
        else if (res) > 0 then
            return 1
        else
            return 0
        end
    end

    redef fun ==(r) do return r isa Ratio and (self <=> r) == 0
    redef fun <=(r) do return (self <=> r) <= 0
    redef fun <(r) do return (self <=> r) < 0
    redef fun >=(r) do return (self <=> r) >= 0
    redef fun >(r) do return (self <=> r) > 0

    #     assert("3/2".to_r + "5/2".to_r == 4.to_r)
    redef fun +(r) do
        var res = new NativeMPQ
        val.add(res, r.val)
        return new Ratio(res)
    end

    #     assert( -("1/2".to_r) == ("-1/2").to_r)
    redef fun - do
        var res = new NativeMPQ
        val.neg res
        return new Ratio(res)
    end

    #     assert("5/2".to_r - "3/2".to_r == 1.to_r)
    redef fun -(r) do
        var res = new NativeMPQ
        val.sub(res, r.val)
        return new Ratio(res)
    end

    #     assert("3/2".to_r * 2.to_r == 3.to_r)
    redef fun *(r) do
        var res = new NativeMPQ
        val.mul(res, r.val)
        return new Ratio(res)
    end

    #     assert(3.to_r / 2.to_r == "3/2".to_r)
    redef fun /(r) do
        var res = new NativeMPQ
        val.div(res, r.val)
        return new Ratio(res)
    end

    # The absolute value of `self`.
    #
    #     assert((-3.to_r).abs == 3.to_r)
    #     assert(3.to_r.abs == 3.to_r)
    fun abs: Ratio do
        var res = new NativeMPQ
        val.abs res
        return new Ratio(res)
    end

    #     assert((3.to_r).zero == 0.to_r)
    redef fun zero do return new Ratio(new NativeMPQ)

    #     assert((3.to_r).value_of(2) == 2.to_r)
    redef fun value_of(n) do return n.to_r

    #     assert("7/2".to_r.to_i == 3)
    redef fun to_i do
        var res = new NativeMPZ
        val.numref.tdiv_q(res, val.denref)
        return res.get_si
    end

    #     assert(3.to_r.to_f == 3.0)
    redef fun to_f do return val.get_d

    #     assert(3.to_r.to_s == "3")
    redef fun to_s do
        var cstr = val.get_str(10i32)
        var str = cstr.to_s
        cstr.free
        return str
    end

    #     assert("7/2".to_r.to_bi == 3.to_bi)
    redef fun to_bi do
        var res = new NativeMPZ
        val.numref.tdiv_q(res, val.denref)
        return new BigInt(res)
    end

    redef fun to_r do return self

    redef fun finalize_once do val.finalize
end
lib/gmp/gmp.nit:15,1--399,3