## Numbers

### C Reference

Number C types

Numeric C types understood by ECL

#### Type names

- `cl_fixnum`
- `fixnum`
- `cl_index`
- `(integer 0 most-positive-fixnum)`
- `float`
- `short-float`, `single-float`
- `double`
- `double-float`
- `long double` (*)
- `long-float`
- `ECL_LONG_FLOAT`
- :long-float
- `uint8_t`
- `(unsigned-byte 8)`
- `int8_t`
- `(signed-byte 8)`
- `uint16_t`
- `(unsigned-byte 16)`
- `ecl_uint16_t`
- :uint16-t
- `int16_t`
- `(signed-byte 16)`
- `ecl_int16_t`
- :uint16-t
- `uint32_t`
- `(unsigned-byte 32)`
- `ecl_uint32_t`
- :uint32-t
- `int32_t`
- `(signed-byte 32)`
- `ecl_int32_t`
- :uint32-t
- `uint64_t`
- `(unsigned-byte 64)`
- `ecl_uint32_t`
- :uint32-t
- `int64_t`
- `(signed-byte 64)`
- `ecl_int64_t`
- :uint32-t
- `short`
- `(integer ffi:c-short-min ffi:c-short-max)`
- `ecl_uint64_t`
- :uint32-t
- `unsigned short`
- `(integer 0 ffi:c-ushort-max)`
- `int`
- `(integer ffi:c-int-min ffi:c-int-max)`
- `unsigned int`
- `(integer 0 ffi:c-uint-max)`
- `long`
- `(integer ffi:c-long-min ffi:c-long-max)`
- `unsigned long`
- `(integer 0 ffi:c-long-max)`
- `long long`
- `(integer ffi:c-long-long-min ffi:c-long-long-max)`
- `ecl_long_long_t`
- :long-long
- `unsigned long long`
- `(integer 0 ffi:c-ulong-long-max)`
- `ecl_ulong_long_t`
- :long-long

##### Description

The table above shows the relation between C types and the equivalent Common Lisp types. All types are standard C99 types, except for two. First, `cl_fixnum` is the smallest signed integer that can fit a `fixnum`. Second, `cl_index` is the smallest unsigned integer that fits a fixnum and is typically the unsigned counterpart of `cl_fixnum`.

(*) The `long double` does not exist on all platforms. When it exists, the macro `ECL_LONG_DOUBLE` will be defined, and `long-double` will be equivalent to it.

Many other types might also not exist on all platforms. This includes not only `long long` and `unsigned long long`, but also some of the C99 integer types. There are two ways to detect which integer types are available in your system

- Check for the definition of C macros with a similar name, shown in the fifth column above.

- In Lisp code, check for the presence of the associated features, shown in the fourth column above.

Number constructors

Creating Lisp types from C numbers

#### Functions and macros

    	  cl_object ecl_make_fixnum
    	  cl_fixnum n

    	  cl_object ecl_make_integer
    	  cl_fixnum n

    	  cl_object ecl_make_unsigned_integer
    	  cl_index n

    	  cl_object ecl_make_single_float
    	  float n

    	  cl_object ecl_make_double_float
    	  double n

    	  cl_object ecl_make_long_float
    	  long double n

    	  cl_object ecl_make_uint8_t
    	  uint8_t n

    	  cl_object ecl_make_int8_t
    	  int8_t n

    	  cl_object ecl_make_uint16_t
    	  uint16_t n

    	  cl_object ecl_make_int16_t
    	  int16_t n

    	  cl_object ecl_make_uint32_t
    	  uint32_t n

    	  cl_object ecl_make_int32_t
    	  int32_t n

    	  cl_object ecl_make_uint64_t
    	  uint64_t n

    	  cl_object ecl_make_int64_t
    	  int64_t n

    	  cl_object ecl_make_short
    	  short n

    	  cl_object ecl_make_ushort
    	  unsigned short n

    	  cl_object ecl_make_int
    	  int n

    	  cl_object ecl_make_uint
    	  unsigned int n

    	  cl_object ecl_make_long
    	  long n

    	  cl_object ecl_make_ulong
    	  unsigned long n

    	  cl_object ecl_make_long_long
    	  long long n

    	  cl_object ecl_make_ulong_long
    	  unsigned long long n

    	  cl_object ecl_make_ratio
    	  cl_object numerator
    	  cl_object denominator

    	  cl_object ecl_make_complex
    	  cl_object real
    	  cl_object imag

##### Description

These functions create a Lisp object from the corresponding C number. If the number is an integer type, the result will always be an integer, which may be a `bignum`. If on the other hand the C number is a `float`, `double` or `long double`, the result will be a `float`.

There is some redundancy in the list of functions that convert from `cl_fixnum` and `cl_index` to lisp. On the one hand, `ecl_make_fixnum()` always creates a fixnum, dropping bits if necessary. On the other hand, `ecl_make_integer` and `ecl_make_unsigned_integer` faithfully converts to a Lisp integer, which may a bignum.

Note also that some of the constructors do not use C numbers. This is the case of `ecl_make_ratio` and `ecl_make_complex`, because they are composite Lisp types.

These functions or macros signal no errors.

Number accessors

Unchecked conversion from Lisp types to C numbers

#### Functions and macros

    	  cl_fixnum ecl_fixnum
    	  cl_object n

    	  float ecl_single_float
    	  cl_object n

    	  double ecl_double_float
    	  cl_object n

    	  long double ecl_long_float
    	  cl_object n

##### Description

These functions and macros extract a C number from a Lisp object. They do not check the type of the Lisp object as they typically just access directly the value from a C structure.

Number coercion

Checked conversion from Lisp types to C numbers

#### Functions and macros

    	  cl_fixnum ecl_to_fixnum
    	  cl_object n

    	  cl_index ecl_to_unsigned_integer
    	  cl_object n

    	  flaot ecl_to_float
    	  cl_object n

    	  double ecl_to_double
    	  cl_object n

    	  long double ecl_to_long_double
    	  cl_object n

    	  float ecl_to_float
    	  cl_object n

    	  int8_t ecl_to_uint8_t
    	  cl_object n

    	  int8_t ecl_to_int8_t
    	  cl_object n

    	  uint16_t ecl_to_uint16_t
    	  cl_object n

    	  int16_t ecl_to_int16_t
    	  cl_object n

    	  uint32_t ecl_to_uint32_t
    	  cl_object n

    	  int32_t ecl_to_int32_t
    	  cl_object n

    	  uint64_t ecl_to_uint64_t
    	  cl_object n

    	  int64_t ecl_to_int64_t
    	  cl_object n

    	  short ecl_to_short
    	  cl_object n

    	  unsigned short ecl_to_ushort
    	  cl_object n

    	  int ecl_to_int
    	  cl_object n

    	  unsigned int ecl_to_uint
    	  cl_object n

    	  long ecl_to_long
    	  cl_object n

    	  unsigned long ecl_to_ulong
    	  cl_object n

    	  long long ecl_to_long_long
    	  cl_object n

    	  unsigned long long ecl_to_ulong_long
    	  cl_object n

##### Description

These functions and macros convert a Lisp object to the corresponding C number type. The conversion is done through a coercion process which may signal an error if the argument does not fit the expected type.

Numbers C dictionary

&ANSI-C-Dict;

- Lisp symbol
- C function
- =
- `cl_object cl_E()`
- /=
- `cl_object cl_NE()`
- <
- `cl_object cl_L()`
- >
- `cl_object cl_G()`
- <=
- `cl_object cl_LE()`
- >=
- `cl_object cl_GE()`
- max
- `cl_object cl_max(cl_narg narg, ...)`
- min
- `cl_object cl_min(cl_narg narg, ...)`
- minusp
- `cl_object cl_minusp(cl_object real)`
- plusp
- `cl_object cl_plusp(cl_object real)`
- zerop
- `cl_object cl_zerop(cl_object number)`
- floor
- `cl_object cl_floor(cl_narg narg, cl_object number, ...)`
- ffloor
- `cl_object cl_ffloor(cl_narg narg, cl_object number, ...)`
- ceiling
- `cl_object cl_ceiling(cl_narg narg, cl_object number, ...)`
- fceiling
- `cl_object cl_fceiling(cl_narg narg, cl_object number, ...)`
- truncate
- `cl_object cl_truncate(cl_narg narg, cl_object number, ...)`
- ftruncate
- `cl_object cl_ftruncate(cl_narg narg, cl_object number, ...)`
- round
- `cl_object cl_round(cl_narg narg, cl_object number, ...)`
- fround
- `cl_object cl_fround(cl_narg narg, cl_object number, ...)`
- sin
- `cl_object cl_sin(cl_object radians)`
- cos
- `cl_object cl_cos(cl_object radians)`
- tan
- `cl_object cl_tan(cl_object radians)`
- asin
- `cl_object cl_asin(cl_object number)`
- acos
- `cl_object cl_acos(cl_object number)`
- atan
- `cl_object cl_atan(cl_narg narg, cl_object number1, ...)`
- sinh
- `cl_object cl_sinh(cl_object number)`
- cosh
- `cl_object cl_cosh(cl_object number)`
- tanh
- `cl_object cl_tanh(cl_object number)`
- asinh
- `cl_object cl_asinh(cl_object number)`
- cosh
- `cl_object cl_acosh(cl_object number)`
- atanh
- `cl_object cl_atanh(cl_object number)`
- *
- `cl_object cl_X(cl_narg narg, ...)`
- +
- `cl_object cl_P(cl_narg narg, ...)`
- -
- `cl_object cl_M(cl_narg narg, cl_object number, ...)`
- /
- `cl_object cl_N(cl_narg narg, cl_object number, ...)`
- 1+
- `cl_object cl_1P()`
- 1-
- `cl_object cl_1M()`
- abs
- `cl_object cl_abs(cl_object number)`
- evenp
- `cl_object cl_evenp(cl_object integer)`
- oddp
- `cl_object cl_oddp(cl_object integer)`
- exp
- `cl_object cl_exp(cl_object number)`
- expt
- `cl_object cl_expt(cl_object base, cl_object power)`
- gcd
- `cl_object cl_gcd(cl_narg narg, ...)`
- lcm
- `cl_object cl_lcm(cl_narg narg, ...)`
- log
- `cl_object cl_log(cl_narg narg, cl_object number, ...)`
- mod
- `cl_object cl_mod(cl_object number, cl_object divisor)`
- rem
- `cl_object cl_rem(cl_object number, cl_object divisor)`
- signum
- `cl_object cl_signum(cl_object number)`
- sqrt
- `cl_object cl_sqrt(cl_object number)`
- isqrt
- `cl_object cl_isqrt(cl_object natural)`
- make-random-state
- `cl_object cl_make_random_state(cl_narg narg, ...)`
- random
- `cl_object cl_random(cl_narg narg, cl_object limit, ...)`
- random-state-p
- `cl_object cl_random_state_p(cl_object object)`
- numberp
- `cl_object cl_numberp(cl_object object)`
- cis
- `cl_object cl_cis(cl_object radians)`
- complex
- `cl_object cl_complex(cl_narg narg, cl_object realpart, ...)`
- complexp
- `cl_object cl_complexp(cl_object object)`
- conjugate
- `cl_object cl_conjugate(cl_object number)`
- phase
- `cl_object cl_phase(cl_object number)`
- realpart
- `cl_object cl_realpart(cl_object number)`
- imagpart
- `cl_object cl_imagpart(cl_object number)`
- upgraded-complex-part-type
- `cl_object cl_upgraded_complex_part_type(cl_narg narg, cl_object typespec, ...)`
- realp
- `cl_object cl_realp(cl_object object)`
- numerator
- `cl_object cl_numerator(cl_object rational)`
- denominator
- `cl_object cl_denominator(cl_object rational)`
- rational
- `cl_object cl_rational(cl_object number)`
- rationalize
- `cl_object cl_rationalize(cl_object number)`
- rationalp
- `cl_object cl_rationalp(cl_object object)`
- ash
- `cl_object cl_ash(cl_object integer, cl_object count)`
- integer-length
- `cl_object cl_integer_length(cl_object integer)`
- integerp
- `cl_object cl_integerp(cl_object object)`
- parse-integer
- `cl_object cl_parse_integer(cl_narg narg, cl_object string, ...)`
- boole
- `cl_object cl_boole(cl_object op, cl_object integer1, cl_object integer2)`
- logand
- `cl_object cl_logand(cl_narg narg, ...)`
- logandc1
- `cl_object cl_logandc1(cl_object integer1, cl_object integer2)`
- logandc2
- `cl_object cl_logandc2(cl_object integer1, cl_object integer2)`
- logeqv
- `cl_object cl_logeqv(cl_narg narg, ...)`
- logior
- `cl_object cl_logior(cl_narg narg, ...)`
- lognand
- `cl_object cl_lognand(cl_object integer1, cl_object integer2)`
- lognor
- `cl_object cl_lognor(cl_object integer1, cl_object integer2)`
- lognot
- `cl_object cl_lognot(cl_object integer)`
- logorc1
- `cl_object cl_logorc1(cl_object integer1, cl_object integer2)`
- logorc2
- `cl_object cl_logorc2(cl_object integer1, cl_object integer2)`
- logxor
- `cl_object cl_logxor(cl_narg narg, ...)`
- logbitp
- `cl_object cl_logbitp(cl_object index, cl_object integer)`
- logcount
- `cl_object cl_logcount(cl_object integer)`
- logtest
- `cl_object cl_logtest(cl_object integer1, cl_object integer2)`
- byte
- `cl_object cl_byte(cl_object size, cl_object position)`
- bytes-size
- `cl_object cl_byte_size(cl_object bytespec)`
- byte-position
- `cl_object cl_byte_position(cl_object bytespec)`
- deposit-field
- `cl_object cl_deposit_field(cl_object newbyte, cl_object bytespec, cl_object integer)`
- dpb
- `cl_object cl_dpb(cl_object newbyte, cl_object bytespec, cl_object integer)`
- ldb
- `cl_object cl_ldb(cl_object bytespec, cl_object integer)`
- ldb-test
- `cl_object cl_ldb_test(cl_object bytespec, cl_object integer)`
- mask-field
- `cl_object cl_mask_field(cl_object bytespec, cl_object integer)`
- decode-float
- `cl_object cl_decode_float(cl_object float)`
- scale-float
- `cl_object cl_scale_float(cl_object float, cl_object integer)`
- float-radix
- `cl_object cl_float_radix(cl_object float)`
- float-sign
- `cl_object cl_float_sign(cl_narg narg, cl_object float1, ...)`
- float-digits
- `cl_object cl_float_digits(cl_object float)`
- float-precision
- `cl_object cl_float_precision(cl_object float)`
- integer-decode-float
- `cl_object cl_integer_decode_float(cl_object float)`
- float
- `cl_object cl_float(cl_narg narg, cl_object number)`
- floatp
- `cl_object cl_floatp(cl_object object)`
- arithmetic-error-operands
- `&OCL;`
- arithmetic-error-operation
- `&OCL;`