Next: , Previous: , Up: Numbers   [Contents][Index]

### 4.5 Numerical operations

See Entry Format, for a summary of the naming conventions used to specify restrictions on the types of arguments to numerical routines. The examples used in this section assume that any numerical constant written using an exact notation is indeed represented as an exact number. Some examples also assume that certain numerical constants written using an inexact notation can be represented without loss of accuracy; the inexact constants were chosen so that this is likely to be true in implementations that use flonums to represent inexact numbers.

procedure: number? object
procedure: complex? object
procedure: real? object
procedure: rational? object
procedure: integer? object

These numerical type predicates can be applied to any kind of argument, including non-numbers. They return `#t` if the object is of the named type, and otherwise they return `#f`. In general, if a type predicate is true of a number then all higher type predicates are also true of that number. Consequently, if a type predicate is false of a number, then all lower type predicates are also false of that number.3

If z is an inexact complex number, then `(real? z)` is true if and only if `(zero? (imag-part z))` is true. If x is an inexact real number, then `(integer? x)` is true if and only if `(= x (round x))`.

```(complex? 3+4i)         ⇒  #t
(complex? 3)            ⇒  #t
(real? 3)               ⇒  #t
(real? -2.5+0.0i)       ⇒  #t
(real? #e1e10)          ⇒  #t
(rational? 6/10)        ⇒  #t
(rational? 6/3)         ⇒  #t
(integer? 3+0i)         ⇒  #t
(integer? 3.0)          ⇒  #t
(integer? 8/4)          ⇒  #t
```

Note: The behavior of these type predicates on inexact numbers is unreliable, since any inaccuracy may affect the result.

procedure: exact? z
procedure: inexact? z

These numerical predicates provide tests for the exactness of a quantity. For any Scheme number, precisely one of these predicates is true.

procedure: exact-integer? object
procedure: exact-nonnegative-integer? object
procedure: exact-rational? object

These procedures test for some very common types of numbers. These tests could be written in terms of simpler predicates, but are more efficient.

procedure: = z1 z2 z3 …
procedure: < x1 x2 x3 …
procedure: > x1 x2 x3 …
procedure: <= x1 x2 x3 …
procedure: >= x1 x2 x3 …

These procedures return `#t` if their arguments are (respectively): equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing.

These predicates are transitive. Note that the traditional implementations of these predicates in Lisp-like languages are not transitive.

Note: While it is not an error to compare inexact numbers using these predicates, the results may be unreliable because a small inaccuracy may affect the result; this is especially true of `=` and `zero?`. When in doubt, consult a numerical analyst.

procedure: zero? z
procedure: positive? x
procedure: negative? x
procedure: odd? x
procedure: even? x

These numerical predicates test a number for a particular property, returning `#t` or `#f`. See note above regarding inexact numbers.

procedure: max x1 x2 …
procedure: min x1 x2 …

These procedures return the maximum or minimum of their arguments.

```(max 3 4)              ⇒  4    ; exact
(max 3.9 4)            ⇒  4.0  ; inexact
```

Note: If any argument is inexact, then the result will also be inexact (unless the procedure can prove that the inaccuracy is not large enough to affect the result, which is possible only in unusual implementations). If `min` or `max` is used to compare numbers of mixed exactness, and the numerical value of the result cannot be represented as an inexact number without loss of accuracy, then the procedure may report a violation of an implementation restriction.4

procedure: + z1 …
procedure: * z1 …

These procedures return the sum or product of their arguments.

```(+ 3 4)                 ⇒  7
(+ 3)                   ⇒  3
(+)                     ⇒  0
(* 4)                   ⇒  4
(*)                     ⇒  1
```
procedure: - z1 z2 …
procedure: / z1 z2 …

With two or more arguments, these procedures return the difference or quotient of their arguments, associating to the left. With one argument, however, they return the additive or multiplicative inverse of their argument.

```(- 3 4)                 ⇒  -1
(- 3 4 5)               ⇒  -6
(- 3)                   ⇒  -3
(/ 3 4 5)               ⇒  3/20
(/ 3)                   ⇒  1/3
```
procedure: 1+ z
procedure: -1+ z

`(1+ z)` is equivalent to `(+ z 1)`; `(-1+ z)` is equivalent to `(- z 1)`.

procedure: abs x

`abs` returns the magnitude of its argument.

```(abs -7)                ⇒  7
```
procedure: quotient n1 n2
procedure: remainder n1 n2
procedure: modulo n1 n2

These procedures implement number-theoretic (integer) division: for positive integers n1 and n2, if n3 and n4 are integers such that then

```(quotient n1 n2)        ⇒  n3
(remainder n1 n2)       ⇒  n4
(modulo n1 n2)          ⇒  n4
```

For integers n1 and n2 with n2 not equal to 0,

```(= n1
(+ (* n2 (quotient n1 n2))
(remainder n1 n2)))
⇒  #t
```

provided all numbers involved in that computation are exact.

The value returned by `quotient` always has the sign of the product of its arguments. `remainder` and `modulo` differ on negative arguments — the `remainder` always has the sign of the dividend, the `modulo` always has the sign of the divisor:

```(modulo 13 4)           ⇒  1
(remainder 13 4)        ⇒  1

(modulo -13 4)          ⇒  3
(remainder -13 4)       ⇒  -1

(modulo 13 -4)          ⇒  -3
(remainder 13 -4)       ⇒  1

(modulo -13 -4)         ⇒  -1
(remainder -13 -4)      ⇒  -1

(remainder -13 -4.0)    ⇒  -1.0  ; inexact
```

Note that `quotient` is the same as `integer-truncate`.

procedure: integer-floor n1 n2
procedure: integer-ceiling n1 n2
procedure: integer-truncate n1 n2
procedure: integer-round n1 n2

These procedures combine integer division with rounding. For example, the following are equivalent:

```(integer-floor n1 n2)
(floor (/ n1 n2))
```

However, the former is faster and does not produce an intermediate result.

Note that `integer-truncate` is the same as `quotient`.

procedure: integer-divide n1 n2
procedure: integer-divide-quotient qr
procedure: integer-divide-remainder qr

`integer-divide` is equivalent to performing both `quotient` and `remainder` at once. The result of `integer-divide` is an object with two components; the procedures `integer-divide-quotient` and `integer-divide-remainder` select those components. These procedures are useful when both the quotient and remainder are needed; often computing both of these numbers simultaneously is much faster than computing them separately.

For example, the following are equivalent:

```(lambda (n d)
(cons (quotient n d)
(remainder n d)))

(lambda (n d)
(let ((qr (integer-divide n d)))
(cons (integer-divide-quotient qr)
(integer-divide-remainder qr))))
```
procedure: gcd n1 …
procedure: lcm n1 …

These procedures return the greatest common divisor or least common multiple of their arguments. The result is always non-negative.

```(gcd 32 -36)            ⇒  4
(gcd)                   ⇒  0

(lcm 32 -36)            ⇒  288
(lcm 32.0 -36)          ⇒  288.0  ; inexact
(lcm)                   ⇒  1
```
procedure: numerator q
procedure: denominator q

These procedures return the numerator or denominator of their argument; the result is computed as if the argument was represented as a fraction in lowest terms. The denominator is always positive. The denominator of 0 is defined to be 1.

```(numerator (/ 6 4))  ⇒  3
(denominator (/ 6 4))  ⇒  2
(denominator (inexact (/ 6 4))) ⇒ 2.0
```
procedure: floor x
procedure: ceiling x
procedure: truncate x
procedure: round x

These procedures return integers. `floor` returns the largest integer not larger than x. `ceiling` returns the smallest integer not smaller than x. `truncate` returns the integer closest to x whose absolute value is not larger than the absolute value of x. `round` returns the closest integer to x, rounding to even when x is halfway between two integers.

Rationale: `round` rounds to even for consistency with the rounding modes required by the IEEE floating point standard.

Note: If the argument to one of these procedures is inexact, then the result will also be inexact. If an exact value is needed, the result should be passed to the `exact` procedure (or use one of the procedures below).

```(floor -4.3)          ⇒  -5.0
(ceiling -4.3)        ⇒  -4.0
(truncate -4.3)       ⇒  -4.0
(round -4.3)          ⇒  -4.0

(floor 3.5)           ⇒  3.0
(ceiling 3.5)         ⇒  4.0
(truncate 3.5)        ⇒  3.0
(round 3.5)           ⇒  4.0  ; inexact

(round 7/2)           ⇒  4    ; exact
(round 7)             ⇒  7
```
procedure: floor->exact x
procedure: ceiling->exact x
procedure: truncate->exact x
procedure: round->exact x

These procedures are similar to the preceding procedures except that they always return an exact result. For example, the following are equivalent

```(floor->exact x)
(exact (floor x))
```

except that the former is faster and has fewer range restrictions.

procedure: rationalize x y
procedure: rationalize->exact x y

`rationalize` returns the simplest rational number differing from x by no more than y. A rational number r1 is simpler than another rational number r2 if r1=p1/q1 and r2=p2/q2 (both in lowest terms) and |p1|<=|p2| and |q1|<=|q2|. Thus 3/5 is simpler than 4/7. Although not all rationals are comparable in this ordering (consider 2/7 and 3/5) any interval contains a rational number that is simpler than every other rational number in that interval (the simpler 2/5 lies between 2/7 and 3/5). Note that 0=0/1 is the simplest rational of all.

```(rationalize (exact .3) 1/10)  ⇒ 1/3    ; exact
(rationalize .3 1/10)          ⇒ #i1/3  ; inexact
```

`rationalize->exact` is similar to `rationalize` except that it always returns an exact result.

procedure: simplest-rational x y
procedure: simplest-exact-rational x y

`simplest-rational` returns the simplest rational number between x and y inclusive; `simplest-exact-rational` is similar except that it always returns an exact result.

These procedures implement the same functionality as `rationalize` and `rationalize->exact`, except that they specify the input range by its endpoints; `rationalize` specifies the range by its center point and its (half-) width.

procedure: exp z
procedure: log z
procedure: sin z
procedure: cos z
procedure: tan z
procedure: asin z
procedure: acos z
procedure: atan z
procedure: atan y x

These procedures compute the usual transcendental functions. `log` computes the natural logarithm of z (not the base ten logarithm). `asin`, `acos`, and `atan` compute arcsine, arccosine, and arctangent, respectively. The two-argument variant of `atan` computes `(angle (make-rectangular x y))` (see below).

In general, the mathematical functions log, arcsine, arccosine, and arctangent are multiply defined. For nonzero real x, the value of log x is defined to be the one whose imaginary part lies in the range minus pi (exclusive) to pi (inclusive). log 0 is undefined. The value of log z when z is complex is defined according to the formula With log defined this way, the values of arcsine, arccosine, and arctangent are according to the following formulae: The above specification follows Common Lisp: the Language, which in turn cites Principal Values and Branch Cuts in Complex APL; refer to these sources for more detailed discussion of branch cuts, boundary conditions, and implementation of these functions. When it is possible these procedures produce a real result from a real argument.

procedure: sqrt z

Returns the principal square root of z. The result will have either positive real part, or zero real part and non-negative imaginary part.

procedure: expt z1 z2

Returns z1 raised to the power z2:

procedure: make-rectangular x1 x2
procedure: make-polar x3 x4
procedure: real-part z
procedure: imag-part z
procedure: magnitude z
procedure: angle z
procedure: conjugate z

Suppose x1, x2, x3, and x4 are real numbers and z is a complex number such that Then `make-rectangular` and `make-polar` return z, `real-part` returns x1, `imag-part` returns x2, `magnitude` returns x3, and `angle` returns x4. In the case of `angle`, whose value is not uniquely determined by the preceding rule, the value returned will be the one in the range minus pi (exclusive) to pi (inclusive).

`conjugate` returns the complex conjugate of z.

The procedures `exact` and `inexact` implement the natural one-to-one correspondence between exact and inexact integers throughout an implementation-dependent range.

procedure: inexact z
procedure: exact->inexact z

`inexact` returns an inexact representation of z. The value returned is the inexact number that is numerically closest to the argument. If an exact argument has no reasonably close inexact equivalent, then a violation of an implementation restriction may be reported; MIT/GNU Scheme signals an error of type `condition-type:bad-range-argument` in this case.

The procedure `exact->inexact` has been deprecated by R7RS.

procedure: inexact z
procedure: exact->inexact z

`inexact` returns an inexact representation of z. The value returned is the inexact number that is numerically closest to the argument. If an exact argument has no reasonably close inexact equivalent, then a violation of an implementation restriction may be reported; MIT/GNU Scheme signals an error of type `condition-type:bad-range-argument` in this case.

`exact` returns an exact representation of z. The value returned is the exact number that is numerically closest to the argument. If an inexact argument has no reasonably close exact equivalent, then a violation of an implementation restriction may be reported; in MIT/GNU Scheme this case does not occur because all inexact numbers are representable as exact numbers.

The procedure `inexact->exact` has been deprecated by R7RS.

### (3)

In MIT/GNU Scheme the `rational?` procedure is the same as `real?`, and the `complex?` procedure is the same as `number?`.

### (4)

MIT/GNU Scheme signals an error of type `condition-type:bad-range-argument` in this case.

Next: , Previous: , Up: Numbers   [Contents][Index]