.. include:: ../../global.rst .. _`number types`: Number Types ============ Numbers in :lname:`Idio` are either "small" integer :ref:`fixnums ` or "arbitrary" precision :ref:`bignums ` which can be integers, floating point numbers and support a notion of exactness. There is no support for non-finite quantities such as *Nan* or infinities. You can also use the :lname:`C` base types, ``C/char``, ``C/int``, etc. and supported ``typedef``\ s thereof, although they are usually passed verbatim within :lname:`C`-oriented modules like :ref:`libc ` and operations involving them only accept like types. Reader Forms ------------ Reading numbers or, rather, identifying numbers as distinct from "words", is complicated as we need to differentiate between, say, ``3e3``, a number, and ``2pi``, a symbol (almost certainly referencing a number). Broadly, a number looks like: * :samp:`[+-]?[0-9]+` * :samp:`[+-]?[0-9]+.[0-9]*` * :samp:`[+-]?[0-9]+.[0-9]*{E}[+-]?[0-9]+` (There must be a numeric part before any ``.`` otherwise it will be interpreted as the :ref:`value-index ` operator.) The exponent character, :samp:`{E}` in the last example, can be one of several characters: * for base-16 numbers (see below): ``e`` and ``E`` quite obviously clash with the possible digits of hexadecimal numbers so for base-16 numbers you can use the exponent characters ``s``/``S`` or ``l``/``L`` * other exponent-able numbers can use ``d``/``D``, ``e``/``E``, ``f``/``F`` -- and ``s``/``S`` and ``l``/``L`` Hence, ``+10``, ``1.``, ``-20.1``, ``0.3e1``, ``-4e-5``, ``6L7`` are all valid number formats and a number will be constructed by the reader. Non-base-10 Numbers ^^^^^^^^^^^^^^^^^^^ There are several reader input forms for non-base-10 numbers all of which effectively call :ref:`read-number ` with an appropriate `radix`: .. csv-table:: Non-base-10 reader number formats :header: "form", "radix", "example", "decimal equivalent" :widths: auto :align: left ``#b``, 2, ``#b101``, 5 ``#o``, 8, ``#o101``, 65 ``#d``, 10, ``#d101``, 101 ``#x``, 16, ``#x101``, 257 ``read-number`` supports bases up to 36 although there are no dedicated reader input forms. Number Predicates ----------------- .. _`integer?`: .. idio:function:: integer? o test if `o` is an integer a fixnum or an integer bignum :param o: object to test :return: ``#t`` if `o` is an integer, ``#f`` otherwise .. _`number?`: .. idio:function:: number? o test if `o` is a number fixnum or bignum :param o: object to test :return: ``#t`` if `o` is an number, ``#f`` otherwise Number Constructors ------------------- .. _`unicode/unicode->integer`: .. idio:function:: unicode/unicode->integer cp convert `cp` to an integer :param cp: unicode to convert :return: integer conversion of `cp` :rtype: fixnum .. _`read-number`: .. idio:function:: read-number src [radix] read a number from `src` :param str: source to read from :type str: handle or string :param radix: use radix, defaults to 10 :type radix: fixnum, optional :return: number ``read-number`` supports bases up to 36 for which the normal hexadecimal digits are extended to all ASCII ``Alphabetic`` code points: ``0-9a-z`` and ``0-9A-Z`` :Example: .. code-block:: idio read-number "i9" 19 ; 351 (18 * 19 + 9) Number Functions ---------------- .. _`+`: .. idio:function:: + [n ...] add numbers :param n: number :type n: number :return: the result of adding the arguments :rtype: number If any arguments are bignums then every argument is converted to a bignum before calculating the result. An attempt is made to convert the result to a fixnum if possible. ``+`` with no argument returns 0. .. _`-`: .. idio:function:: - n1 [n2 ...] subtract numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of subtracting the arguments :rtype: number If any arguments are bignums then every argument is converted to a bignum before calculating the result. An attempt is made to convert the result to a fixnum if possible. ``-`` with one argument is equivalent to :samp:`0 - {n1}`. ``-`` with more than one argument is equivalent to :samp:`r = {n1}` then repeating across the remaining arguments with :samp:`r = {r} - {n2}`, :samp:`r = {r} - {n3}`, etc.. .. _`*`: .. idio:function:: * [n ...] multiply numbers :param n: number :type n: number :return: the result of multiplying the arguments :rtype: number If any arguments are bignums then every argument is converted to a bignum before calculating the result. An attempt is made to convert the result to a fixnum if possible. ``*`` with no argument returns 1. .. _`/`: .. idio:function:: / n1 [n2 ...] divide numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of dividing the arguments :rtype: number All arguments are converted to bignums before calculating the result. An attempt is made to convert the result to a fixnum if possible. ``/`` with one argument is equivalent to :samp:`1 / {n1}`. ``/`` with more than one argument is equivalent to :samp:`r = {n1}` then repeating across the remaining arguments with :samp:`r = {r} / {n2}`, :samp:`r = {r} / {n3}`, etc.. .. _`lt`: .. idio:function:: lt n1 [n2 ...] apply the less-than comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. ``lt`` with one argument is ``#t``. ``lt`` with more than one argument has each subsequent argument compared to the one to its left. The result is ``#t`` if all subsequent arguments are less-than the argument to their left otherwise the result is ``#f``. .. _`le`: .. idio:function:: le n1 [n2 ...] apply the less-than-or-equal comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. ``le`` with one argument is ``#t``. ``le`` with more than one argument has each subsequent argument compared to the one to its left. The result is ``#t`` if all subsequent arguments are less-than-or-equal to the argument to their left otherwise the result is ``#f``. .. _`eq`: .. idio:function:: eq n1 [n2 ...] apply the equality comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. ``eq`` with one argument is ``#t``. ``eq`` with more than one argument has each subsequent argument compared to the one to its left. The result is ``#t`` if all subsequent arguments are equal to the argument to their left otherwise the result is ``#f``. .. _`ne`: .. idio:function:: ne n1 [n2 ...] apply the inequality comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. ``ne`` with one argument is ``#t``. ``ne`` with more than one argument has each subsequent argument compared to the one to its left. The result is ``#t`` if all subsequent arguments are not equal to the argument to their left otherwise the result is ``#f``. .. _`ge`: .. idio:function:: ge n1 [n2 ...] apply the greater-than-or-equal comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. ``ge`` with one argument is ``#t``. ``ge`` with more than one argument has each subsequent argument compared to the one to its left. The result is ``#t`` if all subsequent arguments are greater-than-or-equal the argument to their left otherwise the result is ``#f``. .. _`gt`: .. idio:function:: gt n1 [n2 ...] apply the greater-than comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. ``gt`` with one argument is ``#t``. ``gt`` with more than one argument has each subsequent argument compared to the one to its left. The result is ``#t`` if all subsequent arguments are greater-than the argument to their left otherwise the result is ``#f``. .. _`binary-*`: .. idio:function:: binary-* n1 n2 multiply two numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of multiplying the arguments :rtype: number If the arguments are C/ types then the C arithmetic function is invoked. Otherwise, if any arguments are bignums then every argument is converted to a bignum before calculating the result. An attempt is made to convert the result to a fixnum if possible. The use of the function ``binary-*`` is normally the result of the ``*`` infix operator. .. _`binary-+`: .. idio:function:: binary-+ n1 n2 add two numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of adding the arguments :rtype: number If the arguments are C/ types then the C arithmetic function is invoked. Otherwise, if any arguments are bignums then every argument is converted to a bignum before calculating the result. An attempt is made to convert the result to a fixnum if possible. The use of the function ``binary-+`` is normally the result of the ``+`` infix operator. .. _`binary--`: .. idio:function:: binary-- n1 n2 subtract two numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of subtracting the arguments :rtype: number If the arguments are C/ types then the C arithmetic function is invoked. Otherwise, if any arguments are bignums then every argument is converted to a bignum before calculating the result. An attempt is made to convert the result to a fixnum if possible. The use of the function ``binary--`` is normally the result of the ``-`` infix operator. .. _`binary-/`: .. idio:function:: binary-/ n1 n2 divide two numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of dividing the arguments :rtype: number If the arguments are C/ types then the C arithmetic function is invoked. Otherwise, all arguments are converted to bignums before calculating the result. An attempt is made to convert the result to a fixnum if possible. The use of the function ``binary-/`` is normally the result of the ``/`` infix operator. .. _`binary-lt`: .. idio:function:: binary-lt n1 n2 apply the less-than comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. The use of the function ``binary-lt`` is normally the result of the ``lt`` infix operator. .. _`binary-le`: .. idio:function:: binary-le n1 n2 apply the less-than-or-equal comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. The use of the function ``binary-le`` is normally the result of the ``le`` infix operator. .. _`binary-eq`: .. idio:function:: binary-eq n1 n2 apply the equality comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. The use of the function ``binary-eq`` is normally the result of the ``eq`` infix operator. .. _`binary-ne`: .. idio:function:: binary-ne n1 n2 apply the inequality comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. The use of the function ``binary-ne`` is normally the result of the ``ne`` infix operator. .. _`binary-ge`: .. idio:function:: binary-ge n1 n2 apply the greater-than-or-equal comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. The use of the function ``binary-ge`` is normally the result of the ``ge`` infix operator. .. _`binary-gt`: .. idio:function:: binary-gt n1 n2 apply the greater-than comparator to numbers :param n1: number :type n1: number :param n2: number :type n2: number :return: the result of comparing the arguments :rtype: boolean If any arguments are bignums then every argument is converted to a bignum before calculating the result. The use of the function ``binary-gt`` is normally the result of the ``gt`` infix operator. .. include:: ../../commit.rst