6.4. Numbers


6.4. Numbers

Scheme numbers may be classified as integers, rational numbers, real numbers, or complex numbers, although an implementation may support only a subset of these numeric classes. This classification is hierarchical, in that all integers are rational, all rational numbers are real, and all real numbers are complex. The predicates integer?, rational?, real?, and complex? described in Section 6.2 are used to determine into which of these classes a number falls.

A Scheme number may also be classified as exact or inexact, depending upon the quality of operations used to derive the number and the inputs to these operations. The predicates exact? and inexact? may be used to determine the exactness of a number. Most operations on numbers in Scheme are exactness preserving: if given exact operands they return exact values, and if given inexact operands or a combination of exact and inexact operands they return inexact values.

Exact integer and rational arithmetic is typically supported to arbitrary precision; the size of an integer or of the denominator or numerator of a ratio is limited only by system storage constraints. Although other representations are possible, inexact numbers are typically represented by oating-point numbers supported by the host computer's hardware or by system software. Complex numbers are typically represented as ordered pairs (real-part, imag-part), where real-part and imag-part are exact integers, exact rationals, or oating-point numbers.

Scheme numbers are written in a straightforward manner not much different from ordinary conventions for writing numbers. An exact integer is normally written as a sequence of numerals preceded by an optional sign. For example, 3, +19, -100000, and 208423089237489374 all represent exact integers.

An exact rational number is normally written as two sequences of numerals separated by a slash (/) and preceded by an optional sign. For example, 3/4, -6/5, and 1/1208203823 are all exact rational numbers. A ratio is reduced immediately when it is read and may in fact reduce to an exact integer.

Inexact integers and rational numbers are normally written in either oatingpoint or scientific notation. Floating-point notation consists of a sequence of numerals followed by a decimal point and another sequence of numerals, all preceded by an optional sign. Scientific notation consists of an optional sign, a sequence of numerals, an optional decimal point followed by a second string of numerals, and an exponent; an exponent is written as the letter e followed by an optional sign and a sequence of numerals. For example, 1.0 and -200.0 are valid inexact integers, and 1.5, 0.034, -10e-10 and 1.5e-5 are valid inexact rational numbers. The exponent is the power of ten by which the number preceding the exponent should be scaled, so that 2e3 is equivalent to 2000.0.

The special digit # (hash) may be used in place of a normal digit in certain contexts to signify that the value of the digit is unknown. Numbers that include hash digits are naturally inexact, even if they are written in the style of exact integers or rational numbers. Hash digits may appear after one or more nonhash digits to signify an inexact integer; after one or more nonhash digits in the first or second part of a ratio to specify an inexact rational number; or after one or more nonhash digits before or after the decimal point of an inexact number written in oating-point or scientific notation. No significant (known) digit may follow a hash digit. For example, 1####, -1#/2#, .123### and 1#.### all specify inexact quantities.

Exact and inexact real numbers are written as exact or inexact integers or rational numbers; no provision is made in the syntax of Scheme numbers for nonrational real numbers, i.e., irrational numbers.

Complex numbers may be written in either rectangular or polar form. In rectangular form, a complex number is written as x +yi or x -yi, where x is an integer, rational, or real number and y is an unsigned integer, rational, or real number. The real part, x, may be omitted, in which case it is assumed to be zero. For example, 3+4i, 3.2-3/4i, +i, and -3e-5i are complex numbers written in rectangular form. In polar form, a complex number is written as x@y, where x and y are integer, rational, or real numbers. For example, 1.1@1.764 and -1@-1/2 are complex numbers written in polar form.

The exactness of a numeric representation may be overridden by preceding the representation by either #e or #i. #e forces the number to be exact, and #i forces it to be inexact. For example, 1, #e1, 1/1, #e1/1, #e1.0, #e1e0, and #e1.## all represent the exact integer 1, and #i3/10, 3#/100, 0.3, #i0.3, and 3e-1 all represent the inexact rational 0.3.

Numbers are written by default in base 10, although the special prefixes #b (binary), #o (octal), #d (decimal), and #x (hexadecimal) can be used to specify base 2, base 8, base 10, or base 16. For radix 16, the letters a through f or A through F serve as the additional numerals required to express digit values 10 through 15. For example, #b10101 is the binary equivalent of 2110, #o72 is the octal equivalent of 5810, and #xC7 is the hexadecimal equivalent of 19910. Numbers written in oating-point and scientific notations are always written in base 10.

If both are present, radix and exactness prefixes may appear in either order.

A Scheme implementation may support more than one size of internal representation for inexact quantities. The exponent markers s (short), f (single), d (double), and l (long) may appear in place of the default exponent marker e to override the default size for numbers written in scientific notation. In implementations that support multiple representations, the default size has at least as much precision as double.

A precise grammar for Scheme numbers is included in the description of the formal syntax of Scheme starting on page 277.

Any number can be written in a variety of different ways, but the system printer (see write and display) and number->string express numbers in a compact form, using the fewest number of digits possible while retaining the property that, when read, the printed number is identical to the original number.

The remainder of this section describes procedures that operate on numbers. The type of numeric arguments accepted by these procedures is implied by the name given to the arguments: num for complex numbers (that is, all numbers), real for real numbers, rat for rational numbers, and int for integers.

(exact? num)

procedure

returns: #t if num is exact, #f otherwise

 (exact? 1)  #t (exact? -15/16)  #t (exact? 2.01)  #f (exact? #i77)  #f (exact? #i2/3)  #f (exact? 1.0-2i)  #f (exact? -1#i)  #f 

(inexact? num)

procedure

returns: #t if num is inexact, #f otherwise

 (inexact? -123)  #f (inexact? #i123)  #t (inexact? 1e23)  #t (inexact? 1###)  #t (inexact? 1#/2#)  #t (inexact? #e1#/2#)  #f (inexact? +i)  #f 

(= num1 num2 num3 ...)

procedure

(< real1 real2 real3 ...)

procedure

(> real1 real2 real3 ...)

procedure

(<= real1 real2 real3 ...)

procedure

(>= real1 real2 real3 ...)

procedure

returns: #t if the relation holds, #f otherwise

The predicate = returns #t if its arguments are equal. The predicate < returns #t if its arguments are monotonically increasing, i.e., each argument is greater than the preceding ones, while > returns #t if its arguments are monotonically decreasing. The predicate <= returns #t if its arguments are monotonically nondecreasing, i.e., each argument is not less than the preceding ones, while >= returns #t if its arguments are monotonically nonincreasing.

As implied by the names of the arguments, = is defined for complex arguments while the other relational predicates are defined only for real arguments. Two complex numbers are considered equal if their real and imaginary parts are equal.

 (= 7 7)  #t (= 7 9)  #f (< 2e3 3e2)  #f (<= 1 2 3 3 4 5)  #t (<= 1 2 3 4 5)  #t (> 1 2 2 3 3 4)  #f (>= 1 2 2 3 3 4)  #f (= -1/2 -0.5)  #t (= 2/3 .667)  #f (= 7.2+0i 7.2)  #t (= 7.2-3i 7)  #f (< 1/2 2/3 3/4)  #t (> 8 4.102 2/3 -5)  #t (let ((x 0.218723452))   (< 0.210 x 0.220))  #t (let ((i 1) (v (vector 'a 'b 'c)))   (< -1 i (vector-length v)))  #t (apply < '(1 2 3 4))  #t (apply > '(4 3 3 2))  #f 

(+ num ...)

procedure

returns: the sum of the arguments num ...

When called with no arguments, + returns 0.

 (+)  0 (+ 1 2)  3 (+ 1/2 2/3)  7/6 (+ 3 4 5)  12 (+ 3.0 4)  7.0 (+ 3+4i 4+3i)  7+7i (apply + '(1 2 3 4 5))  15 

(- num1)

procedure

(- num1 num2 num3 ...)

procedure

returns: see explanation

When called with one argument, - returns the negative of num1. Thus, (- num1) is an idiom for (- 0 num1).

When called with two or more arguments, - returns the result of subtracting the sum of the numbers num2 from num1.

The ANSI/IEEE standard includes only one- and two-argument variants. The more general form is included in the Revised5 Report.

 (- 3)  -3 (- -2/3)  2/3 (- 4 3.0)  1.0 (- 3.25+4.25i 1/4+1/4i)  3.0+4.0i (- 4 3 2 1)  -2 

(* num ...)

procedure

returns: the product of the arguments num ...

When called with no arguments, * returns 1.

 (*)  1 (* 3.4)  3.4 (* 1 1/2)  1/2 (* 3 4 5.5)  66.0 (* 1+2i 3+4i)  -5+10i (apply * '(1 2 3 4 5))  120 

(/ num1)

procedure

(/ num1 num2 num3 ...)

procedure

returns: see explanation

When called with one argument, / returns the reciprocal of num1. That is, (/ num1) is an idiom for (/ 1 num1).

When called with two or more arguments, / returns the result of dividing num1 by the product of the remaining arguments num2 .

The ANSI/IEEE standard includes only one- and two-argument variants. The more general form is included in the Revised5 Report.

 (/ -17)  -1/17 (/ 1/2)  2 (/ .5)  2.0 (/ 3 4)  3/4 (/ 3.0 4)  .75 (/ -5+10i 3+4i)  1+2i (/ 60 5 4 3 2)  1/2 

(zero? num)

procedure

returns: #t if num is zero, #f otherwise

zero? is equivalent to (lambda (x) (= x 0)).

 (zero? 0)  #t (zero? 1)  #f (zero? (- 3.0 3.0))  #t (zero? (+ 1/2 1/2))  #f (zero? 0+0i)  #t (zero? 0.0-0.0i)  #t 

(positive? real)

procedure

returns: #t if real is greater than zero, #f otherwise

positive? is equivalent to (lambda (x) (> x 0)).

 (positive? 128)  #t (positive? 0.0)  #f (positive? 1.8e-15)  #t (positive? -2/3)  #f (positive? .001-0.0i)  #t 

(negative? real)

procedure

returns: #t if real is less than zero, #f otherwise

negative? is equivalent to (lambda (x) (< x 0)).

 (negative? -65)  #t (negative? 0)  #f (negative? -0.0121)  #t (negative? 15/16)  #f (negative? -7.0+0.0i)  #t 

(even? int)

procedure

returns: #t if int is even, #f otherwise

 (even? 0)  #t (even? 1)  #f (even? 2.0)  #t (even? -120762398465)  #f (even? 2.0+0.0i)  #t 

(odd? int)

procedure

returns: #t if int is odd, #f otherwise

 (odd? 0)  #f (odd? 1)  #t (odd? 2.0)  #f (odd? -120762398465)  #t (odd? 2.0+0.0i)  #f 

(quotient int1 int2)

procedure

returns: the integer quotient of int1 and int2

 (quotient 45 6)  7 (quotient 6.0 2.0)  3.0 (quotient 3.0 -2)  -1.0 

(remainder int1 int2)

procedure

returns: the integer remainder of int1 and int2

The result of remainder has the same sign as int1.

 (remainder 16 4)  0 (remainder 5 2)  1 (remainder -45.0 7)  -3.0 (remainder 10.0 -3.0)  1.0 (remainder -17 -9)  -8 

(modulo int1 int2)

procedure

returns: the integer modulus of int1 and int2

The result of modulo has the same sign as int2.

 (modulo 16 4)  0 (modulo 5 2)  1 (modulo -45.0 7)  4.0 (modulo 10.0 -3.0)  -2.0 (modulo -17 -9)  -8 

(truncate real)

procedure

returns: the integer closest to real toward zero

 (truncate 19)  19 (truncate 2/3)  0 (truncate -2/3)  0 (truncate 17.3)  17.0 (truncate -17/2)  -8 

(floor real)

procedure

returns: the integer closest to real toward -1

 (floor 19)  19 (floor 2/3)  0 (floor -2/3)  -1 (floor 17.3)  17.0 (floor -17/2)  -9 

(ceiling real)

procedure

returns: the integer closest to real toward +1

 (ceiling 19)  19 (ceiling 2/3)  1 (ceiling -2/3)  0 (ceiling 17.3)  18.0 (ceiling -17/2)  -8 

(round real)

procedure

returns: the integer closest to real

If real is exactly between two integers, the closest even integer is returned.

 (round 19)  19 (round 2/3)  1 (round -2/3)  -1 (round 17.3)  17.0 (round -17/2)  -8 (round 2.5)  2.0 (round 3.5)  4.0 

(abs real)

procedure

returns: the absolute value of real

abs is equivalent to (lambda (x) (if (< x 0) (- x) x)). abs and magnitude (see page 150) are identical for real inputs.

 (abs 1)  1 (abs -3/4)  3/4 (abs 1.83)  1.83 (abs -0.093)  0.093 

(max real1 real2 ...)

procedure

returns: the maximum of real1 real2 ...

 (max 4 -7 2 0 -6)  4 (max 1/2 3/4 4/5 5/6 6/7)  6/7 (max 1.5 1.3 -0.3 0.4 2.0 1.8)  2.0 (max 5 2.0)  5.0 (max -5 -2.0)  -2.0 (let ((ls '(7 3 5 2 9 8)))   (apply max ls))  9 

(min real1 real2 ...)

procedure

returns: the minimum of real1 real2 ...

 (min 4 -7 2 0 -6)  -7 (min 1/2 3/4 4/5 5/6 6/7)  1/2 (min 1.5 1.3 -0.3 0.4 2.0 1.8)  -0.3 (min 5 2.0)  2.0 (min -5 -2.0)  -5.0 (let ((ls '(7 3 5 2 9 8)))   (apply min ls))  2 

(gcd int ...)

procedure

returns: the greatest common divisor of its arguments int ...

The result is always nonnegative, i.e., factors of 1 are ignored. When called with no arguments, gcd returns 0.

 (gcd)  0 (gcd 34)  34 (gcd 33.0 15.0)  3.0 (gcd 70 -42 28)  14 

(lcm int ...)

procedure

returns: the least common multiple of its arguments int ...

The result is always nonnegative, i.e., common multiples of 1 are ignored. Although lcm should probably return 1 when called with no arguments, it is defined to return 1. If one or more of the arguments is 0, lcm returns 0.

 (lcm)  1 (lcm 34)  34 (lcm 33.0 15.0)  165.0 (lcm 70 -42 28)  420 (lcm 17.0 0)  0 

(expt num1 num2)

procedure

returns: num1 raised to the num2 power

If both arguments are 0, expt returns 1.

 (expt 2 10)  1024 (expt 2 -10)  1/1024 (expt 2 -10.0)  9.765625e-4 (expt -1/2 5)  -1/32 (expt 3.0 3)  27.0 (expt +i 2)  -1 

(exact->inexact num)

procedure

returns: an inexact representation for num

If num is already inexact, it is returned unchanged. If no inexact representation for num is supported by the implementation, an error may be signaled.

 (exact->inexact 3)  3.0 (exact->inexact 3.0)  3.0 (exact->inexact -1/4)  -.25 (exact->inexact 3+4i)  3.0+4.0i (exact->inexact (expt 10 20))  1e20 

(inexact->exact num)

procedure

returns: an exact representation for num

If num is already exact, it is returned unchanged. If no exact representation for num is supported by the implementation, an error may be signaled.

 (inexact->exact 3.0)  3 (inexact->exact 3)  3 (inexact->exact -.25)  -1/4 (inexact->exact 3.0+4.0i)  3+4i (inexact->exact 1e20)  100000000000000000000 

(rationalize real1 real2)

procedure

returns: see below

rationalize returns the simplest rational number that differs from real1 by no more than real2. A rational number q1 = n1=m1 is simpler than another rational number q2 = n2=m2 if |n1| |n2| and |m1| m2| and either |n1| < |n2| or |m1| < |m2|.

 (rationalize 3/10 1/10)  1/3 (rationalize .3 1/10)  0.3333333333333333 (eqv? (rationalize .3 1/10) #i1/3)  #t 

(numerator rat)

procedure

returns: the numerator of rat

If rat is an integer, the numerator is rat.

 (numerator 9)  9 (numerator 9.0)  9.0 (numerator 2/3)  2 (numerator -9/4)  -9 (numerator -2.25)  -9.0 

(denominator rat)

procedure

returns: the denominator of rat

If rat is an integer, the denominator is 1.

 (denominator 9)  1 (denominator 9.0)  1.0 (denominator 2/3)  3 (denominator -9/4)  4 (denominator -2.25)  4.0 

(real-part num)

procedure

returns: the real component of num

If num is real, real-part returns num.

 (real-part 3+4i)  3 (real-part -2.3+0.7i)  -2.3 (real-part -i)  0 (real-part 17.2)  17.2 (real-part -17/100)  -17/100 

(imag-part num)

procedure

returns: the imaginary component of num

If num is real, imag-part returns zero.

 (imag-part 3+4i)  4 (imag-part -2.3+0.7i)  0.7 (imag-part -i)  -1 (imag-part 17.2)  0.0 (imag-part -17/100)  0 

(make-rectangular real1 real2)

procedure

returns: a complex number with real component real1 and imaginary component real2

 (make-rectangular -2 7)  -2+7i (make-rectangular 2/3 -1/2)  2/3-1/2i (make-rectangular 3.2 5.3)  3.2+5.3i 

(make-polar real1 real2)

procedure

returns: a complex number with magnitude real1 and angle real2

 (make-polar 2 0)  2 (make-polar 2.0 0.0)  2.0+0.0i (make-polar 1.0 (asin -1.0))  0.0-1.0i (eqv? (make-polar 7.2 -0.588) 7.2@-0.588)  #t 

(angle num)

procedure

returns: the angle part of the polar representation of num

The range of the result is −ϖ (exclusive) to +ϖ (inclusive).

 (angle 7.3@1.5708)  1.5708 (angle 5.2)  0.0 

(magnitude num)

procedure

returns: the magnitude of num

magnitude and abs (see page 146) are identical for real arguments. The magnitude of a complex number x + yi is .

 (magnitude 1)  1 (magnitude -3/4)  3/4 (magnitude 1.83)  1.83 (magnitude -0.093)  0.093 (magnitude 3+4i)  5 (magnitude 7.25@1.5708)  7.25 

(sqrt num)

procedure

returns: the principal square root of num

Implementations are encouraged, but not required, to return exact results for exact inputs to sqrt whenever feasible.

 (sqrt 16)  4 (sqrt 1/4)  1/2 (sqrt 4.84)  2.2 (sqrt -4.84)  0.0+2.2i (sqrt 3+4i)  2+1i (sqrt -3.0-4.0i)  1.0-2.0i 

(exp num)

procedure

returns: e to the num power

 (exp 0.0)  1.0 (exp 1.0)  2.7182818284590455 (exp -.5)  0.6065306597126334 

(log num)

procedure

returns: the natural log of num

The log of a complex number z is defined as follows.

log(z = log(magnitude(z)) + i angle (z)

 (log 1.0)  0.0 (log (exp 1.0))  1.0 (/ (log 100) (log 10))  2.0 (log (make-polar (exp 2.0) 1.0))  2.0+1.0i 

(sin num)

procedure

(cos num)

procedure

(tan num)

procedure

returns: the sine, cosine, or tangent of num

The argument is specified in radians.

(asin num)

procedure

(acos num)

procedure

returns: the arc sine or the arc cosine of num

The result is in radians. The arc sine and arc cosine of a complex number z are defined as follows.

(atan num)

procedure

(atan real1 real2)

procedure

returns: see explanation

When passed a single complex argument num (the first form), atan returns the arc tangent of num. The arc tangent of a complex number z is defined as follows.

tan1 (z) = (log(1+iz) log (1 iz))/(2i)

When passed two real arguments (the second form), atan is equivalent to (lambda (x y) (angle (make-rectangular x y))).

(string->number string)

procedure

(string->number string radix )

procedure

returns: the number represented by string, or #f

If string is a valid representation of a number, that number is returned, otherwise #f is returned. The number is interpreted in radix radix, which must be an exact integer in the set f2; 8; 10; 16g. If not specified, radix defaults to 10. Any radix specifier within string, e.g., #x, overrides the radix argument.

 (string->number "0")  0 (string->number "3.4e3")  3400.0 (string->number "#x#e-2e2")  -738 (string->number "#e-2e2" 16)  -738 (string->number "#i15/16")  0.9375 (string->number "10" 16)  16 

(number->string num)

procedure

(number->string num radix )

procedure

returns: an external representation of num as a string

The num is expressed in radix radix, which must be an exact integer in the set f2; 8; 10; 16g. If not specified, radix defaults to 10. In any case, no radix specifier appears in the resulting string.

The external representation is such that, when converted back into a number using string->number, the resulting numeric value is equivalent to num. That is, for all inputs:

 (eqv? (string->number         (number->string num radix )      radix )        num) 

returns #t. Inexact results are expressed using the fewest number of significant digits possible without violating the above restriction.

 (number->string 3.4)  "3.4" (number->string 1e2)  "100.0" (number->string 1e23)  "1e23" (number->string -7/2)  "-7/2" (number->string 220/9 16)  "DC/9" 




The Scheme Programming Language
The Scheme Programming Language
ISBN: 026251298X
EAN: 2147483647
Year: 2003
Pages: 98

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net