Gauche supports the following types of numbers
There’s no limit of the size of number except the memory of the machine.
Both denominator and numerator are represented by exact integers. There’s no limit of the size of number except the memory of the machine.
Using double
-type of underlying C compiler, usually IEEE 64-bit
floating point number.
Real part and imaginary part are represented by inexact floating-point real numbers.
• Number classes: | ||
• Numerical predicates: | ||
• Numerical comparison: | ||
• Arithmetics: | ||
• Numerical conversions: | ||
• Basic bitwise operations: | ||
• Endianness: |
These classes consist a class hierarchy of number objects.
<complex>
inherits <number>
, <real>
inherits
<complex>
,<rational>
inherits <real>
and <integer>
inherits <rational>
.
Note that these classes do not exactly correspond to the
number hierarchy defined in R7RS. Especially,
only exact integers are the instances of the <integer>
class. That is,
(integer? 1) ⇒ #t (is-a? 1 <integer>) ⇒ #t (is-a? 1 <real>) ⇒ #t (integer? 1.0) ⇒ #t (is-a? 1.0 <integer>) ⇒ #f (is-a? 1.0 <real>) ⇒ #t (class-of (expt 2 100)) ⇒ #<class <integer>> (class-of (sqrt -3)) ⇒ #<class <complex>>
[R7RS base]
Returns #t
if obj is a number, a complex number, a real number,
a rational number or an integer, respectively. In Gauche, a set of
numbers is the same as a set of complex numbers.
A set of rational numbers is the same as a set of real numbers,
except +inf.0
, -inf.0
and +nan.0
(since we have only limited-precision floating numbers).
(complex? 3+4i) ⇒ #t (complex? 3) ⇒ #t (real? 3) ⇒ #t (real? -2.5+0.0i) ⇒ #t (real? #e1e10) ⇒ #t (integer? 3+0i) ⇒ #t (integer? 3.0) ⇒ #t (real? +inf.0) ⇒ #t (real? +nan.0) ⇒ #t (rational? +inf.0) ⇒ #f (rational? +nan.0) ⇒ #f
Note: R6RS adopts more strict definition on exactness,
and notably, it defines a complex number with non-exact zero imaginary
part is not a real number. Currently Gauche doesn’t have
exact complex numbers, and automatically coerces complex
numbers with zero imaginary part to a real number.
Thus R6RS code that relies on the fact that (real? 1+0.0i)
is
#f
won’t work with Gauche.
[R6RS]
In Gauche these are just an alias of real?
, rational?
and integer?
. They are provided for R6RS compatibility.
The difference of those and non -valued
versions in R6RS is
that these returns #t
if obj is a complex number
with nonexact zero imaginary part. Since Gauche doesn’t distinguish
complex numbers with zero imaginary part and real numbers, we don’t
have the difference.
[R7RS base]
Returns #t
if obj is an exact number and an inexact number,
respectively.
(exact? 1) ⇒ #t (exact? 1.0) ⇒ #f (inexact? 1) ⇒ #f (inexact? 1.0) ⇒ #t (exact? (modulo 5 3)) ⇒ #t (inexact? (modulo 5 3.0)) ⇒ #f
[R7RS base]
Same as (and (exact? obj) (integer? obj))
, but more efficient.
[R7RS base]
Returns #t
if a number z equals to zero.
(zero? 1) ⇒ #f (zero? 0) ⇒ #t (zero? 0.0) ⇒ #t (zero? -0.0) ⇒ #t (zero? 0.0+0.0i) ⇒ #t
[R7RS base]
Returns #t
if a real number x is positive and negative,
respectively. It is an error to pass a non-real number.
Note that minus zero (-0.0
) is zero, not negative.
Returns #t
if a number x is a minus zero (-0.0
),
#f
otherwise.
An error is signaled if x is not a number.
[R7RS inexact]
For real numbers, returns #f
iff the given number
is finite, infinite, or NaN, respectively.
For non-real complex numbers, finite?
returns #t
iff
both real and imaginary components are finite, infinite?
returns #t
if at least either real or imaginary component
is infinite, and nan?
returns #t
if at least either
real or imaginary component is NaN. (Note: It is incompatible
to R6RS, in which these procedures must raise an error if
the given argument is non-real number.)
In R7RS, these procedures are in (scheme inexact)
library.
[R7RS base]
Returns #t
if an integer n is odd and even,
respectively. It is an error to pass a non-integral number.
(odd? 3) ⇒ #t (even? 3) ⇒ #f (odd? 3.0) ⇒ #t
[R7RS fixnum]
Returns #t
iff n is an exact integer whose internal
representation is fixnum and bignum, respectively.
R7RS-large defines fixnum?
in scheme.fixnum
library;
bignum?
is Gauche’s extension.
Portable Scheme programs don’t need to care about the internal
representation of integer. These are for certain low-level
routines that does particular optimization.
See scheme.fixnum
- R7RS fixnums, for the comprehensive fixnum library.
[R7RS flonum]
Returns #t
if x is a number represented by a floating-point
number, #f
otherwise. In Gauche, inexact real numbers
are flonums.
See scheme.flonum
- R7RS flonum, for comprehensive flonum library.
Returns #t
if x is a number represented by an exact
non-integral number, or #f
otherwise. Internally, a number
that returns #t
for it is represented as a pair of two
exact integers.
Usually you don’t need to distinguish ratnums from exact integers; you can treat them as exact numbers. In performance-sensitive code, however, ratnum slows down computation a lot and you may want to detect that case.
[R7RS base]
If all the numbers z are equal numerically, returns #t
.
(= 2 2) ⇒ #t (= 2 3) ⇒ #f (= 2/4 1/2) ⇒ #t
Exactness doesn’t affect numerical comparison; inexact 1.0 and
exact 1 are =
to each other. Positive inexact zero (0.0) and
negative inexact zero (-0.0) are also =
to each other.
To distinguish numerically equal
exact and inexact number, you have to use eqv?
or equal?
.
(= 2 2.0) ⇒ #t (= 2 2.0 2.0+0i) ⇒ #t (= -0.0 0.0) ⇒ #t ;; cf: (eqv? 2 2.0) ⇒ #f (eqv? -0.0 0.0) ⇒ #f
Note that +nan.0
would never =
to any number, including itself.
(= +nan.0 +inf.0) ⇒ #f (= +nan.0 +nan.0) ⇒ #f (let ((x +nan.0)) (= x x)) ⇒ #f
[R7RS base]
Returns #t
If all the real numbers x are
monotonically increasing,
monotonically nondecreasing, monotonically decreasing, or monotonically
nonincreasing, respectively.
Since (= 0.0 -0.0)
is #t
, (> 0.0 -0.0)
is #f
.
If any of the argument is NaN, the result is always #f
.
Hence (< x y) ⇒ #f
does not imply (>= x y) ⇒ #t
.
[R7RS base] Returns a maximum or minimum number in the given real numbers, respectively. If any of the arguments are NaN, NaN is returned.
See also find-min
and find-max
in
Selection and searching in collection.
Returns a maximum and minimum number in the given real numbers.
See also find-min&max
in
Selection and searching in collection.
Returns #t
iff two numbers are approximately equal within
the given error tolerance.
#f
.
#t
iff the other one is also
infinity of the same sign.
(<= (abs (- x y)) (max (* (max (abs x) (abs y)) relative-tolerance) absolute-tolerance))
If at least one of x or y are non-real complex
number, magnitude
is used in place of abs
.
When omitted, relative-tolerance is assumed to be
(flonum-epsilon)
, and absolute-tolerance is
(least-positive-flonum)
.
That is, by default, approx=?
tolerates
1 ULP (unit in the last place) error.
The absolute-tolerance argument is useful when arguments are close to zero, in which case relative tolerance becomes too small.
Returns flonums with the following characteristics, respectively:
flonum-epsilon
Returns the least positive flonum e such that, for a normalized
flonum x
, x
and (* x (+ 1.0 e))
are distinguishable.
greatest-positive-flonum
Returns the greatest positive finite flonum. It is
DBL_MAX
in C.
least-positive-flonum
Returns the least positive flonum representable as floating-point number. If the platform supports denormalized flonum, it returns the least positive denormalized floating-point number. Otherwise, it returns the least positive normalized floating-point number.
least-positive-normalized-flonum
Returns the least positive flonum representable as normalized floating-point
number. It is DBL_MIN
in C.
NB: For portable programs, R7RS scheme.flonum
module
provides constants fl-epsilon
, fl-greatest
, and
fl-least
(see scheme.flonum
- R7RS flonum).
Deprecated.
These are old names for least-positive-normalized-flonum
and
least-positive-flonum
. We renamed to make the semantics clear.
least-fixnum
and greatest-fixnum
.
[R7RS base]
Returns the sum or the product of given numbers, respectively.
If no argument is given, (+)
yields 0 and (*)
yields 1.
[R7RS base] If only one number z1 is given, returns its negation and reciprocal, respectively.
If more than one number are given, returns:
z1 - z2 - z3 ... z1 / z2 / z3 ...
respectively.
(- 3) ⇒ -3 (- -3.0) ⇒ 3.0 (- 5+2i) ⇒ -5.0-2.0i (/ 3) ⇒ 1/3 (/ 5+2i) ⇒ 0.172413793103448-0.0689655172413793i (- 5 2 1) ⇒ 2 (- 5 2.0 1) ⇒ 2.0 (- 5+3i -i) ⇒ 5.0+2.0i (/ 14 6) ⇒ 7/3 (/ 6+2i 2) ⇒ 3.0+1.0i
Note: Gauche didn’t have exact rational number support until 0.8.8;
before that, /
coerced the result to inexact even if both
divisor and dividend were exact numbers, when the result wasn’t
a whole number. It is not the case anymore.
If the existing code relies on the old behavior, it runs
very slowly on the newer versions of Gauche, since the calculation
proceeds with exact rational arithmetics that is much slower than
floating point arithmetics. You want to use /.
below
to use fast inexact arithmetics (unless you
need exact results).
Like +
, *
, -
, and /
, but the arguments
are coerced to inexact number. So they always return inexact number.
These are useful when you know you don’t need exact calculation
and want to avoid accidental overhead of bignums and/or exact
rational numbers.
[R7RS+ base] For real number z, returns an absolute value of it. For complex number z, returns the magnitude of the number. The complex part is Gauche extension.
(abs -1) ⇒ 1 (abs -1.0) ⇒ 1.0 (abs 1+i) ⇒ 1.4142135623731
[R7RS base] Returns the quotient, remainder and modulo of dividing an integer n1 by an integer n2. The result is an exact number only if both n1 and n2 are exact numbers.
Remainder and modulo differ when either one of the arguments is negative. Remainder R and quotient Q have the following relationship.
n1 = Q * n2 + R
where abs(Q) = floor(abs(n1)/abs(n2))
.
Consequently, R’s sign is always the same as n1’s.
On the other hand, modulo works as expected for positive n2,
regardless of the sign of n1
(e.g. (modulo -1 n2) == n2 - 1
).
If n2 is negative, it is mapped to the positive case by
the following relationship.
modulo(n1, n2) = −modulo(−n1, −n2)
Consequently, modulo’s sign is always the same as n2’s.
(remainder 10 3) ⇒ 1 (modulo 10 3) ⇒ 1 (remainder -10 3) ⇒ -1 (modulo -10 3) ⇒ 2 (remainder 10 -3) ⇒ 1 (modulo 10 -3) ⇒ -2 (remainder -10 -3) ⇒ -1 (modulo -10 -3) ⇒ -1
Calculates the quotient and the remainder of dividing integer n1 by integer n2 simultaneously, and returns them as two values.
[R6RS]
These are integer division procedures introduced in R6RS.
Unlike quotient
, modulo
and remainder
,
these procedures can take non-integral values.
The dividend x can be an arbitrary real number,
and the divisor y can be non-zero real number.
div
returns an integer n, and mod
returns
a real number m, such that:
Examples:
(div 123 10) ⇒ 12 (mod 123 10) ⇒ 3 (div 123 -10) ⇒ -12 (mod 123 -10) ⇒ 3 (div -123 10) ⇒ -13 (mod -123 10) ⇒ 7 (div -123 -10) ⇒ 13 (mod -123 -10) ⇒ 7 (div 123/7 10/9) ⇒ 15 (mod 123/7 10/9) ⇒ 19/21 ;; 123/7 = 10/9 * 15 + 19/21 (div 14.625 3.75) ⇒ 3.0 (mod 14.625 3.75) ⇒ 3.375 ;; 14.625 = 3.75 * 3.0 + 3.375
For a nonnegative integer x and an integer y,
The results of div
and mod
matches
those of quotient
and remainder
. If x
is negative, they differ, though.
div-and-mod
calculates both div
and mod
and returns their results in two values.
div0 and mod0 are similar, except the range of m:
(div0 123 10) ⇒ 12 (mod0 123 10) ⇒ 3 (div0 127 10) ⇒ 13 (mod0 127 10) ⇒ -3 (div0 127 -10) ⇒ -13 (mod0 127 -10) ⇒ -3 (div0 -127 10) ⇒ -13 (mod0 -127 10) ⇒ 3 (div0 -127 -10) ⇒ 13 (mod0 -127 -10) ⇒ 3
div0-and-mod0
calculates both div0
and mod0
and returns their results in two values.
Here’s a visualization of R6RS and R7RS division and modulo operations: http://blog.practical-scheme.net/gauche/20100618-integer-divisions It might help to grasp how they works.
[R7RS base] These are integer division operators introduced in R7RS. The names explicitly indicate how they behave when numerator and/or denominator is/are negative.
The arguments n and d must be an integer. If any of them are inexact, the result is inexact. If all of them are exact, the result is exact. Also, d must not be zero.
Given numerator n, denominator d, quotient q and remainder r, the following relations are always kept.
r = n - dq abs(r) < abs(d)
Now, (floor-quotient n d)
and (truncate-quotient n d)
are the same as (floor (/ n d))
and
(truncate (/ n d))
, respectively.
The *-remainder
counterparts are
derived from the above relation.
The /
-suffixed version, floor/
and truncate/
,
returns corresponding quotient and remainder as two values.
(floor-quotient 10 -3) ⇒ -4 (floor-remainder 10 -3) ⇒ -2 (truncate-quotient 10 -3) ⇒ -3 (truncate-remainder 10 -3) ⇒ 1
R7RS division library (scheme.division
) introduces
other variation of integer divisions
(see scheme.division
- R7RS integer division).
[R7RS base] Returns the greatest common divisor or the least common multiplier of the given integers, respectively
Arguments must be integers, but doesn’t need to be exact. If any of arguments is inexact, the result is inexact.
Returns a lazy sequence of regular continued fraction expansion of finite real number x. An error is raised if x is infinite or NaN, or not a real number. The returned sequence is lazy, so the terms are calculated as needed.
(continued-fraction 13579/2468) ⇒ (5 1 1 122 1 9) (+ 5 (/ (+ 1 (/ (+ 1 (/ (+ 122 (/ (+ 1 (/ 9)))))))))) ⇒ 13579/2468 (continued-fraction (exact 3.141592653589793)) ⇒ (3 7 15 1 292 1 1 1 2 1 3 1 14 3 3 2 1 3 3 7 2 1 1 3 2 42 2) (continued-fraction 1.5625) ⇒ (1.0 1.0 1.0 3.0 2.0)
[R7RS base] Returns the numerator and denominator of a rational number q.
[R7RS base] Returns the simplest rational approximation q of a real number x, such that the difference between x and q is no more than the error bound ebound.
Note that Gauche doesn’t have inexact rational number, so if x and/or ebound is inexact, the result is coerced to floating point representation. If you want an exact result, coerce the arguments to exact number first.
(rationalize 1234/5678 1/1000) ⇒ 5/23 (rationalize 3.141592653589793 1/10000) ⇒ 3.141509433962264 (rationalize (exact 3.141592653589793) 1/10000) ⇒ 333/106 (rationalize (exact 3.141592653589793) 1/10000000) ⇒ 75948/24175 ;; Some edge cases (rationalize 2 +inf.0) ⇒ 0 (rationalize +inf.0 0) ⇒ +inf.0 (rationalize +inf.0 +inf.0) ⇒ +nan.0
[R7RS base]
The argument x must be a real number.
Floor
and ceiling
return a maximum integer that
isn’t greater than x and a minimum integer that isn’t less
than x, respectively.
Truncate
returns an integer that truncates
x towards zero. Round
returns an integer that is closest
to x. If fractional part of x is exactly 0.5, round
returns the closest even integer.
Following Scheme’s general rule, the result is inexact if x is an
inexact number; e.g. (round 2.3)
is 2.0
. If you need
an exact integer by rounding an inexact number, you have to use exact
on the result, or use one of the following procedure ((floor->exact
etc).
These are convenience procedures of the popular
phrase (exact (floor x))
etc.
Returns
min if x<
min x if min<=
x<=
max max if max<
x
If min or max is omitted or #f
, it is regarded
as -inf.0
or +inf.0
, respectively.
Returns an exact integer only if all the given numbers are exact integers.
(clamp 3.1 0.0 1.0) ⇒ 1.0 (clamp 0.5 0.0 1.0) ⇒ 0.5 (clamp -0.3 0.0 1.0) ⇒ 0.0 (clamp -5 0) ⇒ 0 (clamp 3724 #f 256) ⇒ 256
[R7RS inexact]
Transcendental functions. Work for complex numbers as well.
In R7RS, these procedures are in the (scheme inexact)
module.
exp
returns e raised to the power of z. The one-argument
version of log
returns the natural logarithm of z.
The two-argument version of log
is added in R6RS, and returns
base-z2 logarithm of z1.
The two-argument version of atan
returns
(angle (make-rectangular x y))
for the real numbers x
and y
.
See also real-exp
etc. below, for real-only version of these functions.
Hyperbolic trigonometric functions. Work for complex numbers as well.
See also real-sinh
etc. below, for real-only version of these functions.
Convert radians to degrees and vice versa. The argument must be a real number.
[R7RS inexact] Returns a square root of a complex number z. The branch cut scheme is the same as Common Lisp. For real numbers, it returns a positive root.
If z is the square of an exact real number, the return value is also an exact number.
(sqrt 2) ⇒ 1.4142135623730951 (sqrt -2) ⇒ 0.0+1.4142135623730951i (sqrt 256) ⇒ 16 (sqrt 256.0) ⇒ 16.0 (sqrt 81/169) ⇒ 9/13
See also real-sqrt
below, for inexact-real-only version of sqrt
.
[R7RS base] Given an exact nonnegative integer k, returns two exact nonnegative integer s and r that satisfy the following equations:
k = (+ (* s s) r) k < (* (+ s 1) (+ s 1))
(exact-integer-sqrt 782763574)
⇒ 27977 and 51045
[R7RS base]
Returns (* z z)
.
[R7RS base] Returns z1^z2 (z1 powered by z2), where z1 and z2 are complex numbers.
Scheme standard defines (expt 0 0)
as 1 for convenience.
Calculates (modulo (expt base exponent) mod)
efficiently.
The next example shows the last 10 digits of a mersenne prime M_74207281 (2^74207281 - 1)
(- (expt-mod 2 74207281 #e1e10) 1) ⇒ 1086436351
[SRFI-94] Real-only version of elementary functions. An error is signaled unless the arguments are real numbers.
These are useful for performance-sensitive code, for they don’t need to check whether the input is complex. Furthermore, they are subject to constant folding.
Those names are defined in SRFI-94. However, for the portable programs,
you may want to use scheme.flonum
module, which is a part of
R7RS-large and defines
flonum-only versions of elementary functions (see scheme.flonum
- R7RS flonum).
Note: SRFI-94 defines real-log
, which is a two-argument version
of real-only log
, but it takes base argument first, which is
different from R7RS two-argument log
. To avoid confusion,
we don’t support real-log
in the core.
Returns sin(πx), cos(πx), and tan(πx), respectively. An error is signaled if the argument is not a real number. These come handy sometimes, as the following example show:
(use math.const) (real-sin pi) ⇒ 1.2246467991473532e-16 (real-sinpi 1.0) ⇒ 0.0 (real-cos (/ pi 2)) ⇒ 6.123233995736766e-17 (real-cospi 0.5) ⇒ 0.0
Real-only version of hyperbolic functions and their inverses. An error is signaled if the argument is not a real number.
Gamma function and natural logarithmic of absolute value of Gamma function.
NB: Mathematically these functions are defined in complex domain, but currently we only support real number argument.
[R6RS]
These procedures return the width of fixnum (w),
the greatest integer representable by fixnum (2^(w-1) - 1
),
and the least integer representable by fixnum (- 2^(w-1)
),
respectively. You might want to care the fixnum range when
you are writing a performance-critical section.
These names are defined in R6RS. Common Lisp and ChezScheme have
most-positive-fixnum
and most-negative-fixnum
.
NB: Before 0.9.5, fixnum-width
had a bug
to return one smaller than the supposed value.
[R7RS complex]
Creates a complex number from two real numbers, x1 and x2.
make-rectangular
returns x1 + ix2.
make-polar
returns x1e^(ix2).
In R7RS, these procedures are in the (scheme complex)
library.
[R7RS complex]
Decompose a complex number z and returns a real number.
real-part
and imag-part
return z’s real and imaginary
part, respectively. magnitude
and angle
return
z’s magnitude and angle, respectively.
In R7RS, these procedures are in the (scheme complex)
library.
For a given finite floating-point number, returns
a vector of three exact integers, #(m, e, sign)
,
where
x = (* sign m (expt 2.0 e)) sign is either 1, 0 or -1.
If x is +inf.0
or -inf.0
, m is #t
.
If x is +nan.0
, m is #f
.
The API is taken from ChezScheme.
(decode-float 3.1415926) ⇒ #(7074237631354954 -51 1) (* 7074237631354954 (expt 2.0 -51)) ⇒ 3.1415926 (decode-float +nan.0) ⇒ #(#f 0 -1)
This is an inverse of decode-float
. Vector must be
a three-element vector as returned from decode-float
.
(encode-float '#(7074237631354954 -51 1)) ⇒ 3.1415926 (encode-float '#(#t 0 1)) ⇒ +inf.0
[POSIX]
These procedures can be used to compose and decompose floating
point numbers. Fmod
computes the remainder of dividing x
by y, that is, it returns x-n*y where
n is the quotient of x/y rounded towards zero
to an integer. Modf
returns two values; a fractional
part of x and an integral part of x. Frexp
returns two values, fraction and exponent of x,
where x = fraction * 2^exponent, and
0.5 <= |fraction| < 1.0, unless x is zero.
(When x is zero, both fraction and exponent are zero).
Ldexp is a reverse operation of
frexp
; it returns a real number x * 2^n.
(fmod 32.1 10.0) ⇒ 2.1 (fmod 1.5 1.4) ⇒ 0.1 (modf 12.5) ⇒ 0.5 and 12.0 (frexp 3.14) ⇒ 0.785 and 2 (ldexp 0.785 2) ⇒ 3.14
[R7RS base]
Returns an exact or an inexact representation of the
given number z, respectively. Passing an exact number
to exact
, and an inexact number to inexact
, are no-op.
Gauche doesn’t have exact complex number with non-zero imaginary part,
nor exact infinites and NaNs, so passing those to exact
raises
an error.
(inexact 1) ⇒ 1.0 (inexact 1/10) ⇒ 0.1
If an inexact finite real number is passed to exact
,
the simplest exact rational number within the precision of the
floating point representation is returned.
(exact 1.0) ⇒ 1 (exact 0.1) ⇒ 1/10 (exact (/ 3.0)) ⇒ 1/3
For all finite inexact real number x,
(inexact (exact x))
is always eqv?
to
the original number x.
(Note that the inverse doesn’t hold, that is, an exact number n
and (exact (inexact n))
aren’t necessarily the same.
It’s because many (actually, infinite number of) exact numbers
can be mapped to one inexact number.)
To specify the error tolerance when converting inexact real numbers
to exact rational numbers, use rationalize
or real->rational
.
[R5RS] Converts exact number to inexact one, and vice versa.
In fact, exact->inexact
returns the argument as is
if an inexact number is passed, and inexact->exact
returns the argument if an exact number is passed, so
in Gauche they are equivalent to inexact
and exact
,
respectively. Note that other R5RS implementation may raise
an error if passing an inexact number to exact->inexact
,
for example.
Generally exact
and inexact
are preferred,
for they are more concise, and you don’t need to care
whether the argument is exact or inexact numbers.
These procedures are for compatibility with R5RS programs.
Find the simplest rational representation of a finite real
number x within the specified error bounds. This is the low-level
routine called by rationalize
and exact
.
Typically you want to use rationalize
(see Arithmetics)
for this purpose. Use real->rational
only when you need finer
control of error bounds.
The result rational value r satisfies the following condition:
(<= (- x lo) r (+ x hi)) ; when open? is #f (< (- x lo) r (+ x hi)) ; otherwise
Note that both hi and lo must be nonnegative.
If hi and/or lo is omitted, it is determined by x:
if x is exact, hi and lo are defaulted to zero; if
x is inexact, hi and lo depend on
the precision of the floating point representation of x.
In the latter case, the open? also depends on x—it is true
if the mantissa of x is odd, and false otherwise, reflecting
the round-to-even rule. So, if you call real->rational
with
one finite number, you’ll get the same result as exact
:
(real->rational 0.1) ⇒ 1/10
Passing zeros to the error bounds makes it return the exact
conversion of the floating number itself (that is, the exact
calculation of (* sign mantissa (expt 2 exponent))
).
(real->rational 0.1 0 0) ⇒ 3602879701896397/36028797018963968
(If you give both hi and lo, but omit open?, we assume closed range.)
[R7RS+ base] These procedures convert a number and its string representation in radix radix system. radix must be between 2 and 36 inclusive. If radix is omitted, 10 is assumed.
Number->string
takes a number z and returns a string.
If z is not an exact integer, radix must be 10.
For the numbers with radix more than 10, lower case alphabet
character is used for digits, unless the optional argument
use-upper? is true, in that case upper case characters are used.
The argument use-upper? is Gauche’s extension.
String->number
takes a string string and parses it
as a number in radix radix system. If the number contains
a decimal point, only radix 10 is allowed. If the given string
can’t be a number, #f
is returned.
The default-exactness optional argument of string->number
is Gauche’s extension, and it must be either #f
(default),
a symbol exact
, or a symbol inexact
.
If it is either symbol, it sets the exactness of the number if
no exactness prefix (#e
or #i
) is given.
If string has an exactness prefix, default-exactness
is irrelevant.
(string->number "2.718281828459045" 10 'exact) ⇒ 543656365691809/200000000000000 (string->number "#i2.718281828459045" 10 'exact) ⇒ 2.718281828459045 (string->number "1/3" 10 'inexact) ⇒ 0.3333333333333333 (string->number "#e1/3" 10 'inexact) ⇒ 1/3
Generic coercion functions. Returns ‘natural’ interpretation of obj
as a number or an exact integer, respectively.
The default methods are defined for numbers and strings; a string is
interpreted by string->number
, and if the string can’t be
interpreted as a number, 0 is returned.
Other obj is simply converted to 0.
If obj is naturally interpreted
as a number that is not an exact integer, x->integer
uses
round
and inexact->exact
to obtain an integer.
Other class may provide a method to customize the behavior.
These procedures treat integers as half-open bit vectors. If an integer is positive, it is regarded as if infinite number of zeros are padded to the left. If an integer is negative, it is regarded in 2’s complement form, and infinite number of 1’s are padded to the left.
In regard to the names of those operations, there are two groups
in the Scheme world; Gauche follows the names of the
original SLIB’s “logical” module, which was rooted in CL.
Another group uses a bit long but descriptive name such as
arithmetic-shift
.
R7RS bitwise library
(see scheme.bitwise
- R7RS bitwise operations) provides additional bitwise operations.
[SRFI-60]
Shifts integer n left with count bits.
If count is negative, ash
shifts n right with
−count bits.
; Note: 6 ≡ [...00110], and ; -6 ≡ [...11010] (ash 6 2) ⇒ 24 ;[...0011000] (ash 6 -2) ⇒ 1 ;[...0000001] (ash -6 2) ⇒ -24 ;[...1101000] (ash -6 -2) ⇒ -2 ;[...1111110]
[SRFI-60]
Returns bitwise and, bitwise inclusive or and bitwise exclusive or
of integers n1 …. If no arguments are given, logand
returns -1
, and logior
and logxor
returns 0
.
[SRFI-60] Returns bitwise not of an integer n.
[SRFI-60]
≡ (not (zero? (logand n1 n2 …)))
[SRFI-60]
Returns #t
if index-th bit of integer n is 1,
#f
otherwise.
Returns an integer such that n’s bit is set where set-bits is 1, and cleared where clear-bits is 1. If a bit is included in both set-bits and clear-bits, it is cleared.
It is effectively the same as
(logand (logior n set-bits) (lognot clear-bits))
.
(logset+clear #b11000011 #b00001100 #b01000001) ⇒ 142 ;; #b10001110
[R7RS bitwise] Extracts start-th bit (inclusive) to end-th bit (exclusive) from an exact integer n, where start < end.
[R7RS bitwise] If bit is true, sets index-th bit of an exact integer n. If bit is false, resets index-th bit of an exact integer n.
[SRFI-60]
Returns an exact integer, each bit of which is the same as
n except the start-th bit (inclusive) to end-th
bit (exclusive), which is a copy of the lower
(end-start)
-th bits of an exact
integer from.
(number->string (copy-bit-field #b10000000 -1 1 5) 2) ⇒ "10011110" (number->string (copy-bit-field #b10000000 #b010101010 1 7) 2) ⇒ "11010100"
Note: The API of this procedure was originally taken from SLIB,
and at that time,
the argument order was (copy-bit-field n start end from)
.
During the discussion of SRFI-60 the argument order was changed
for the consistency, and the new versions of SLIB followed it.
We didn’t realize the change until recently - before 0.9.4,
this procedure had the old argument order. Code that is using
this procedure needs to be fixed. If you need your code to work
with both versions of Gauche, have the following definition
in your code.
(define (copy-bit-field to from start end) (if (< start end) (let1 mask (- (ash 1 (- end start)) 1) (logior (logand to (lognot (ash mask start))) (ash (logand from mask) start))) from))
[SRFI-60]
If n is positive, returns the number of 1
’s in the
bits of n. If n is negative,
returns the number of 0
’s in the bits of 2’s complement
representation of n.
(logcount 0) ⇒ 0 (logcount #b0010) ⇒ 1 (logcount #b0110) ⇒ 2 (logcount #b1111) ⇒ 4 (logcount #b-0001) ⇒ 0 ;; 2's complement: ....111111 (logcount #b-0010) ⇒ 1 ;; 2's complement: ....111110 (logcount #b-0011) ⇒ 1 ;; 2's complement: ....111101 (logcount #b-0100) ⇒ 2 ;; 2's complement: ....111100
[R7RS bitwise] Returns the minimum number of bits required to represent an exact integer n. Negative integer is assumed to be in 2’s complement form. A sign bit is not considered.
(integer-length 255) ⇒ 8 (integer-length 256) ⇒ 9 (integer-length -256) ⇒ 8 (integer-length -257) ⇒ 9
If n is a power of two, that is, (expt 2 k)
and k >= 0
,
then returns k
. Returns #f
if n is not a power of two.
Returns maximum k such that (expt 2 k)
is a factor of n.
In other words, returns the number of consecutive zero bits from LSB
of n. When n is zero, we return -1
for the
consistency of the following equivalent expression.
This can be calculated by the following expression; this procedure is for speed to save creating intermediate numbers when n is bignum.
(- (integer-length (logxor n (- n 1))) 1)
This procedure is also equivalent to SRFI-60’s log2-binary-factors
and
first-set-bit
(see srfi.60
- Integers as bits).
In the Scheme world you rarely need to know about how the numbers are represented inside the machine. However, it matters when you have to exchange data to/from the outer world in binary representation.
Gauche’s binary I/O procedures, such as in
the binary.io
module (see binary.io
- Binary I/O) and
write-uvector
/read-uvector!
(see Uniform vectors), take optional endian argument
to specify the endianness.
Currently Gauche recognizes the following endiannesses.
big-endian
big
Big-endian. With this endianness, a 32-bit integer #x12345678
will be written out as an octet sequence #x12 #x34 #x56 #x78
.
Gauche has been using big-endian
, but scheme.bytevector
incorporated in R7RS uses big
, so we recognize both.
little-endian
little
Little-endian. With this endianness, a 32-bit integer #x12345678
is written out as an octet sequence #x78 #x56 #x34 #x12
.
Gauche has been using little-endian
, but scheme.bytevector
incorporated in R7RS uses little
, so we recognize both.
arm-little-endian
This is a variation of little-endian
, and used in ARM
processors in some specific modes. It works just like little-endian
,
except reading/writing double-precision floating point number (f64
),
which is written as two little-endian 32bit words ordered by big-endian
(e.g. If machine register’s representation is #x0102030405060708
,
it is written as #x04 #x03 #x02 #x01 #x08 #x07 #x06 #x05
.
When the endian argument is omitted, those procedures
use the parameter default-endian
:
This is a dynamic parameter (see Parameters) to specify the endianness the binary I/O routines use when its endian argument is omitted. The initial value of this parameter is the system’s native endianness.
The system’s native endianness can be queried with the following procedure:
Returns a symbol representing the system’s endianness.