#### 6.6.2.2 Integers

Integers are whole numbers, that is numbers with no fractional part, such as 2, 83, and −3789.

Integers in Guile can be arbitrarily big, as shown by the following example.

```(define (factorial n)
(let loop ((n n) (product 1))
(if (= n 0)
product
(loop (- n 1) (* product n)))))

(factorial 3)
⇒ 6

(factorial 20)
⇒ 2432902008176640000

(- (factorial 45))
⇒ -119622220865480194561963161495657715064383733760000000000
```

Readers whose background is in programming languages where integers are limited by the need to fit into just 4 or 8 bytes of memory may find this surprising, or suspect that Guile’s representation of integers is inefficient. In fact, Guile achieves a near optimal balance of convenience and efficiency by using the host computer’s native representation of integers where possible, and a more general representation where the required number does not fit in the native form. Conversion between these two representations is automatic and completely invisible to the Scheme level programmer.

C has a host of different integer types, and Guile offers a host of functions to convert between them and the `SCM` representation. For example, a C `int` can be handled with `scm_to_int` and `scm_from_int`. Guile also defines a few C integer types of its own, to help with differences between systems.

C integer types that are not covered can be handled with the generic `scm_to_signed_integer` and `scm_from_signed_integer` for signed types, or with `scm_to_unsigned_integer` and `scm_from_unsigned_integer` for unsigned types.

Scheme integers can be exact and inexact. For example, a number written as `3.0` with an explicit decimal-point is inexact, but it is also an integer. The functions `integer?` and `scm_is_integer` report true for such a number, but the functions `exact-integer?`, `scm_is_exact_integer`, `scm_is_signed_integer`, and `scm_is_unsigned_integer` only allow exact integers and thus report false. Likewise, the conversion functions like `scm_to_signed_integer` only accept exact integers.

The motivation for this behavior is that the inexactness of a number should not be lost silently. If you want to allow inexact integers, you can explicitly insert a call to `inexact->exact` or to its C equivalent `scm_inexact_to_exact`. (Only inexact integers will be converted by this call into exact integers; inexact non-integers will become exact fractions.)

Scheme Procedure: integer? x
C Function: scm_integer_p (x)

Return `#t` if x is an exact or inexact integer number, else return `#f`.

```(integer? 487)
⇒ #t

(integer? 3.0)
⇒ #t

(integer? -3.4)
⇒ #f

(integer? +inf.0)
⇒ #f
```
C Function: `int` scm_is_integer `(SCM x)`

This is equivalent to `scm_is_true (scm_integer_p (x))`.

Scheme Procedure: exact-integer? x
C Function: scm_exact_integer_p (x)

Return `#t` if x is an exact integer number, else return `#f`.

```(exact-integer? 37)
⇒ #t

(exact-integer? 3.0)
⇒ #f
```
C Function: `int` scm_is_exact_integer `(SCM x)`

This is equivalent to `scm_is_true (scm_exact_integer_p (x))`.

C Type: scm_t_int8
C Type: scm_t_uint8
C Type: scm_t_int16
C Type: scm_t_uint16
C Type: scm_t_int32
C Type: scm_t_uint32
C Type: scm_t_int64
C Type: scm_t_uint64
C Type: scm_t_intmax
C Type: scm_t_uintmax

The C types are equivalent to the corresponding ISO C types but are defined on all platforms, with the exception of `scm_t_int64` and `scm_t_uint64`, which are only defined when a 64-bit type is available. For example, `scm_t_int8` is equivalent to `int8_t`.

You can regard these definitions as a stop-gap measure until all platforms provide these types. If you know that all the platforms that you are interested in already provide these types, it is better to use them directly instead of the types provided by Guile.

C Function: `int` scm_is_signed_integer `(SCM x, scm_t_intmax min, scm_t_intmax max)`
C Function: `int` scm_is_unsigned_integer `(SCM x, scm_t_uintmax min, scm_t_uintmax max)`

Return `1` when x represents an exact integer that is between min and max, inclusive.

These functions can be used to check whether a `SCM` value will fit into a given range, such as the range of a given C integer type. If you just want to convert a `SCM` value to a given C integer type, use one of the conversion functions directly.

C Function: `scm_t_intmax` scm_to_signed_integer `(SCM x, scm_t_intmax min, scm_t_intmax max)`
C Function: `scm_t_uintmax` scm_to_unsigned_integer `(SCM x, scm_t_uintmax min, scm_t_uintmax max)`

When x represents an exact integer that is between min and max inclusive, return that integer. Else signal an error, either a ‘wrong-type’ error when x is not an exact integer, or an ‘out-of-range’ error when it doesn’t fit the given range.

C Function: `SCM` scm_from_signed_integer `(scm_t_intmax x)`
C Function: `SCM` scm_from_unsigned_integer `(scm_t_uintmax x)`

Return the `SCM` value that represents the integer x. This function will always succeed and will always return an exact number.

C Function: `char` scm_to_char `(SCM x)`
C Function: `signed char` scm_to_schar `(SCM x)`
C Function: `unsigned char` scm_to_uchar `(SCM x)`
C Function: `short` scm_to_short `(SCM x)`
C Function: `unsigned short` scm_to_ushort `(SCM x)`
C Function: `int` scm_to_int `(SCM x)`
C Function: `unsigned int` scm_to_uint `(SCM x)`
C Function: `long` scm_to_long `(SCM x)`
C Function: `unsigned long` scm_to_ulong `(SCM x)`
C Function: `long long` scm_to_long_long `(SCM x)`
C Function: `unsigned long long` scm_to_ulong_long `(SCM x)`
C Function: `size_t` scm_to_size_t `(SCM x)`
C Function: `ssize_t` scm_to_ssize_t `(SCM x)`
C Function: `scm_t_uintptr` scm_to_uintptr_t `(SCM x)`
C Function: `scm_t_ptrdiff` scm_to_ptrdiff_t `(SCM x)`
C Function: `scm_t_int8` scm_to_int8 `(SCM x)`
C Function: `scm_t_uint8` scm_to_uint8 `(SCM x)`
C Function: `scm_t_int16` scm_to_int16 `(SCM x)`
C Function: `scm_t_uint16` scm_to_uint16 `(SCM x)`
C Function: `scm_t_int32` scm_to_int32 `(SCM x)`
C Function: `scm_t_uint32` scm_to_uint32 `(SCM x)`
C Function: `scm_t_int64` scm_to_int64 `(SCM x)`
C Function: `scm_t_uint64` scm_to_uint64 `(SCM x)`
C Function: `scm_t_intmax` scm_to_intmax `(SCM x)`
C Function: `scm_t_uintmax` scm_to_uintmax `(SCM x)`
C Function: `scm_t_intptr` scm_to_intptr_t `(SCM x)`
C Function: `scm_t_uintptr` scm_to_uintptr_t `(SCM x)`

When x represents an exact integer that fits into the indicated C type, return that integer. Else signal an error, either a ‘wrong-type’ error when x is not an exact integer, or an ‘out-of-range’ error when it doesn’t fit the given range.

The functions `scm_to_long_long`, `scm_to_ulong_long`, `scm_to_int64`, and `scm_to_uint64` are only available when the corresponding types are.

C Function: `SCM` scm_from_char `(char x)`
C Function: `SCM` scm_from_schar `(signed char x)`
C Function: `SCM` scm_from_uchar `(unsigned char x)`
C Function: `SCM` scm_from_short `(short x)`
C Function: `SCM` scm_from_ushort `(unsigned short x)`
C Function: `SCM` scm_from_int `(int x)`
C Function: `SCM` scm_from_uint `(unsigned int x)`
C Function: `SCM` scm_from_long `(long x)`
C Function: `SCM` scm_from_ulong `(unsigned long x)`
C Function: `SCM` scm_from_long_long `(long long x)`
C Function: `SCM` scm_from_ulong_long `(unsigned long long x)`
C Function: `SCM` scm_from_size_t `(size_t x)`
C Function: `SCM` scm_from_ssize_t `(ssize_t x)`
C Function: `SCM` scm_from_uintptr_t `(uintptr_t x)`
C Function: `SCM` scm_from_ptrdiff_t `(scm_t_ptrdiff x)`
C Function: `SCM` scm_from_int8 `(scm_t_int8 x)`
C Function: `SCM` scm_from_uint8 `(scm_t_uint8 x)`
C Function: `SCM` scm_from_int16 `(scm_t_int16 x)`
C Function: `SCM` scm_from_uint16 `(scm_t_uint16 x)`
C Function: `SCM` scm_from_int32 `(scm_t_int32 x)`
C Function: `SCM` scm_from_uint32 `(scm_t_uint32 x)`
C Function: `SCM` scm_from_int64 `(scm_t_int64 x)`
C Function: `SCM` scm_from_uint64 `(scm_t_uint64 x)`
C Function: `SCM` scm_from_intmax `(scm_t_intmax x)`
C Function: `SCM` scm_from_uintmax `(scm_t_uintmax x)`
C Function: `SCM` scm_from_intptr_t `(scm_t_intptr x)`
C Function: `SCM` scm_from_uintptr_t `(scm_t_uintptr x)`

Return the `SCM` value that represents the integer x. These functions will always succeed and will always return an exact number.

C Function: `void` scm_to_mpz `(SCM val, mpz_t rop)`

Assign val to the multiple precision integer rop. val must be an exact integer, otherwise an error will be signalled. rop must have been initialized with `mpz_init` before this function is called. When rop is no longer needed the occupied space must be freed with `mpz_clear`. See Initializing Integers in GNU MP Manual, for details.

C Function: `SCM` scm_from_mpz `(mpz_t val)`

Return the `SCM` value that represents val.