Help language development. Donate to The Perl Foundation

P5math zef:lizmat last updated on 2021-09-09
[![Actions Status](](


Raku port of Perl's math built-ins


    use P5math; # exports abs cos crypt exp int log rand sin sqrt


This module tries to mimic the behaviour of Perl's `abs`, `cos`, `crypt`, `exp`, `int`, `log`, `rand`, `sin` and `sqrt` builtins as closely as possible in the Raku Programming Language..


    abs VALUE
    abs     Returns the absolute value of its argument. If VALUE is omitted,
            uses $_.

    cos EXPR
    cos     Returns the cosine of EXPR (expressed in radians). If EXPR is
            omitted, takes the cosine of $_.

            For the inverse cosine operation, you may use the
            "Math::Trig::acos()" function, or use this relation:

                sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }

            Creates a digest string exactly like the crypt(3) function in the
            C library (assuming that you actually have a version there that
            has not been extirpated as a potential munition).

            crypt() is a one-way hash function. The PLAINTEXT and SALT are
            turned into a short string, called a digest, which is returned.
            The same PLAINTEXT and SALT will always return the same string,
            but there is no (known) way to get the original PLAINTEXT from the
            hash. Small changes in the PLAINTEXT or SALT will result in large
            changes in the digest.

            There is no decrypt function. This function isn't all that useful
            for cryptography (for that, look for Crypt modules on your nearby
            CPAN mirror) and the name "crypt" is a bit of a misnomer. Instead
            it is primarily used to check if two pieces of text are the same
            without having to transmit or store the text itself. An example is
            checking if a correct password is given. The digest of the
            password is stored, not the password itself. The user types in a
            password that is crypt()'d with the same salt as the stored
            digest. If the two digests match, the password is correct.

            When verifying an existing digest string you should use the digest
            as the salt (like "crypt($plain, $digest) eq $digest"). The SALT
            used to create the digest is visible as part of the digest. This
            ensures crypt() will hash the new string with the same salt as the
            digest. This allows your code to work with the standard crypt and
            with more exotic implementations. In other words, assume nothing
            about the returned string itself nor about how many bytes of SALT
            may matter.

            Traditionally the result is a string of 13 bytes: two first bytes
            of the salt, followed by 11 bytes from the set "[./0-9A-Za-z]",
            and only the first eight bytes of PLAINTEXT mattered. But
            alternative hashing schemes (like MD5), higher level security
            schemes (like C2), and implementations on non-Unix platforms may
            produce different strings.

            When choosing a new salt create a random two character string
            whose characters come from the set "[./0-9A-Za-z]" (like "join '',
            ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]"). This set
            of characters is just a recommendation; the characters allowed in
            the salt depend solely on your system's crypt library, and Perl
            can't restrict what salts "crypt()" accepts.

            Here's an example that makes sure that whoever runs this program
            knows their password:

                $pwd = (getpwuid($<))[1];

                system "stty -echo";
                print "Password: ";
                chomp($word = <STDIN>);
                print "\n";
                system "stty echo";

                if (crypt($word, $pwd) ne $pwd) {
                    die "Sorry...\n";
                } else {
                    print "ok\n";

            Of course, typing in your own password to whoever asks you for it
            is unwise.

            The crypt function is unsuitable for hashing large quantities of
            data, not least of all because you can't get the information back.
            Look at the Digest module for more robust algorithms.

            If using crypt() on a Unicode string (which potentially has
            characters with codepoints above 255), Perl tries to make sense of
            the situation by trying to downgrade (a copy of) the string back
            to an eight-bit byte string before calling crypt() (on that copy).
            If that works, good. If not, crypt() dies with "Wide character in

            Portability issues: "crypt" in perlport.

    exp EXPR
    exp     Returns me (the natural logarithm base) to the power of EXPR. If
            EXPR is omitted, gives "exp($_)".

    int EXPR
    int     Returns the integer portion of EXPR. If EXPR is omitted, uses $_.
            You should not use this function for rounding: one because it
            truncates towards 0, and two because machine representations of
            floating-point numbers can sometimes produce counterintuitive
            results. For example, "int(-6.725/0.025)" produces -268 rather
            than the correct -269; that's because it's really more like
            -268.99999999999994315658 instead. Usually, the "sprintf",
            "printf", or the "POSIX::floor" and "POSIX::ceil" functions will
            serve you better than will int().

    log EXPR
    log     Returns the natural logarithm (base e) of EXPR. If EXPR is
            omitted, returns the log of $_. To get the log of another base,
            use basic algebra: The base-N log of a number is equal to the
            natural log of that number divided by the natural log of N. For

                sub log10 {
                    my $n = shift;
                    return log($n)/log(10);

            See also "exp" for the inverse operation.

    rand EXPR
    rand    Returns a random fractional number greater than or equal to 0 and
            less than the value of EXPR. (EXPR should be positive.) If EXPR is
            omitted, the value 1 is used. Currently EXPR with the value 0 is
            also special-cased as 1 (this was undocumented before Perl 5.8.0
            and is subject to change in future versions of Perl).
            Automatically calls "srand" unless "srand" has already been
            called. See also "srand".

            Apply "int()" to the value returned by "rand()" if you want random
            integers instead of random fractional numbers. For example,


            returns a random integer between 0 and 9, inclusive.

            (Note: If your rand function consistently returns numbers that are
            too large or too small, then your version of Perl was probably
            compiled with the wrong number of RANDBITS.)

            "rand()" is not cryptographically secure. You should not rely on
            it in security-sensitive situations. As of this writing, a number
            of third-party CPAN modules offer random number generators
            intended by their authors to be cryptographically secure,
            including: Data::Entropy, Crypt::Random, Math::Random::Secure, and

    sin EXPR
    sin     Returns the sine of EXPR (expressed in radians). If EXPR is
            omitted, returns sine of $_.

            For the inverse sine operation, you may use the "Math::Trig::asin"
            function, or use this relation:

                sub asin { atan2($_[0], sqrt(1 - $_[0] * $_[0])) }

    sqrt EXPR
    sqrt    Return the positive square root of EXPR. If EXPR is omitted, uses
            $_. Works only for non-negative operands unless you've loaded the
            "Math::Complex" module.

                use Math::Complex;
                print sqrt(-4);    # prints 2i


Can not use int()

As of this writing (2020.10), it is **not** possible to actually use `int` in your code because of code generation issue caused by the fact that `int` is a built-in native type in Raku.

crypt() not supported on all platforms

The `crypt` function will return `Nil` if it is not supported by the OS.

$_ no longer accessible from caller's scope

In future language versions of Raku, it will become impossible to access the `$_` variable of the caller's scope, because it will not have been marked as a dynamic variable. So please consider changing:


to either:


or, using the subroutine as a method syntax, with the prefix `.` shortcut to use that scope's `$_` as the invocant:



Elizabeth Mattijsen <[email protected]>

Source can be located at: . Comments and Pull Requests are welcome.


Copyright 2018, 2019, 2020, 2021 Elizabeth Mattijsen

Re-imagined from Perl as part of the CPAN Butterfly Plan.

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.