=begin pod

=TITLE class Int

=SUBTITLE Integer (arbitrary-precision)

    class Int is Cool does Real { ... }

C<Int> objects store integral numbers of arbitrary size. C<Int>s are immutable.

There are two main syntax forms for C<Int> literals

    123         # Int in decimal notation
    :16<BEEF>   # Int in radix notations

Both forms allow underscores between any two digits which can serve as visual
separators, but don't carry any meaning:

    5_00000     # five Lakhs
    500_000     # five hundred thousand

=head1 Methods

=head2 routine chr

Defined as:

    multi sub    chr(Int:D ) returns Str:D
    multi method chr(Int:D:) returns Str:D

Usage:

    chr INTEGER
    INTEGER.chr

Returns a one-character string, by interpreting the integer as a Unicode
codepoint number and converting it to the corresponding character.

Example:

    65.chr  # returns "A"
    196.chr # returns "Ä"

=head2 routine expmod

Defined as:

    multi sub    expmod (Int:D: Int $y, Int $mod) returns Int:D
    multi method expmod (Int:D: Int $y, Int $mod) returns Int:D

Usage:

    expmod(INTEGER, POWER, MODULUS)
    INTEGER.expmod(POWER, MODULUS)

Returns the given C<Int> raised to the C<$y> power within modulus C<$mod>.

    say expmod(4, 2, 5);    # 1
    say 7.expmod(2, 5);     # 4

=head2 routine polymod

Defined as:

    method polymod(Int:D: +@mods)      

Usage:

    INTEGER.polymod(LIST)            

Returns a sequence of mod results corresponding to the divisors in C<@mods>.       
If the number of divisors is finite, returns one more result than the number 
of divisors, and the final result is the remainder after all the divisions. 
If the number of divisors is infinite, runs until the remainder is 0. 
The Int version of this method assumes all the divisors are also integers. 
Coerce the invocant to Num or Rat if you wish to use fractional operations.

    say 3661.polymod(60,60,24);                                                  # (1 1 1 0)

    my $seconds = 3600;
    say $seconds.polymod(60,60,24) Z <seconds minutes hours days>;               # ((0 seconds) (0 minutes) (1 hours) (0 days))
    
    # another way to do calculations like the ones above without using polymod
    my $secs = 3661; 
    for 60,60,24 { say $secs mod $_; $secs div= $_ }; say $secs;                 # 1\n1\n1\n0\n

=head2 routine is-prime

Defined as:

    multi sub    is-prime (Int:D $number) returns Bool:D
    multi method is-prime (Int:D:) returns Bool:D

Usage:

    is-prime INTEGER
    INTEGER.is-prime


Returns C<True> if this C<Int> is known to be a prime, or is likely to be a
prime based on a probabilistic Miller-Rabin test.

Returns C<False> if this C<Int> is known not to be a prime.

    say 2.is-prime;         # True
    say is-prime(9);        # False

=head2 routine lsb

Defined as:

    multi method lsb(Int:D:)
    multi sub    lsb(Int:D)

Usage:

    lsb INTEGER
    INTEGER.lsb

Returns L<Nil|/type/Nil> if the number is 0. Otherwise returns the zero-based
index from the right of the first 1 in the binary representation of the
number.

    say 0b01011.lsb;        # 0
    say 0b01010.lsb;        # 1
    say 0b10100.lsb;        # 2
    say 0b01000.lsb;        # 3
    say 0b10000.lsb;        # 4

=head2 routine msb

Defined as:

    multi method msb(Int:D:)
    multi sub    msb(Int:D)

Usage:

    msb INTEGER
    INTEGER.msb

Returns L<Nil|/type/Nil> if the number is 0. Otherwise returns the zero-based
index from the left of the first 1 in the binary representation of the
number.

    say 0b00001.msb;        # 0
    say 0b00011.msb;        # 1
    say 0b00101.msb;        # 2
    say 0b01010.msb;        # 3
    say 0b10011.msb;        # 4

=head2 routine unival

Defined as:

    multi sub    unival(Int:D)  returns Numeric
    multi method unival(Int:D:) returns Numeric

Usage:

    unival INTEGER
    INTEGER.unival

Returns the number represented by the Unicode codepoint with the given integer
number, or L<NaN> if it does not represent a number.

    say ord("¾").unival;    # 0.75
    say 190.unival;         # 0.75
    say unival(65);         # NaN

=head1 Operators

=head2 infix div

    multi sub infix:<div>(Int:D, Int:D) returns Int:D

Does an integer division, rounded down.

=end pod
