## 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;`