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 signaled. 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.