Kawa supports the full Scheme set of number operations with some extensions.
Kawa converts between Scheme number types and Java number types as appropriate.
These numerical type predicates can be applied to any kind of argument. The
real-valued?
procedure returns#t
if the object is a number object and is equal in the sense of=
to some real number object, or if the object is a NaN, or a complex number object whose real part is a NaN and whose imaginary part is zero in the sense ofzero?
. Therational-valued?
andinteger-valued?
procedures return#t
if the object is a number object and is equal in the sense of=
to some object of the named type, and otherwise they return#f
.(real-valued? +nan.0) ⇒ #t (real-valued? +nan.0+0i) ⇒ #t (real-valued? -inf.0) ⇒ #t (real-valued? 3) ⇒ #t (real-valued? -2.5+0.0i) ⇒ #t (real-valued? -2.5+0i) ⇒ #t (real-valued? -2.5) ⇒ #t (real-valued? #e1e10) ⇒ #t (rational-valued? +nan.0) ⇒ #f (rational-valued? -inf.0) ⇒ #f (rational-valued? 6/10) ⇒ #t (rational-valued? 6/10+0.0i) ⇒ #t (rational-valued? 6/10+0i) ⇒ #t (rational-valued? 6/3) ⇒ #t (integer-valued? 3+0i) ⇒ #t (integer-valued? 3+0.0i) ⇒ #t (integer-valued? 3.0) ⇒ #t (integer-valued? 3.0+0.0i) ⇒ #t (integer-valued? 8/4) ⇒ #tNote: These procedures test whether a given number object can be coerced to the specified type without loss of numerical accuracy. Specifically, the behavior of these predicates differs from the behavior of
real?
,rational?
, andinteger?
on complex number objects whose imaginary part is inexact zero.Note: The behavior of these type predicates on inexact number objects is unreliable, because any inaccuracy may affect the result.
Returns
#t
ifz
is both exact and an integer; otherwise returns#f
.(exact-integer? 32) ⇒ #t (exact-integer? 32.0) ⇒ #t (exact-integer? 32/5) ⇒ #f
Returns
#t
ifz
is finite real number (i.e. an infinity and not a NaN), or ifz
is a complex number whose real and imaginary parts are both finite.(finite? 3) ⇒ #t (finite? +inf.0) ⇒ #f (finite? 3.0+inf.0i) ⇒ #f
Return
#t
ifz
is an infinite real number (+int.0
or-inf.0
), or ifz
is a complex number where either real or imaginary parts or both are infinite.(infinite? 5.0) ⇒ #f (infinite? +inf.0) ⇒ #t (infinite? +nan.0) ⇒ #f (infinite? 3.0+inf.0i) ⇒ #t
For a real numer returns whether its is a NaN; for a complex number if the real or imaginary parts or both is a NaN.
(nan? +nan.0) ⇒ #t (nan? 32) ⇒ #f (nan? +nan.0+5.0i) ⇒ #t (nan? 1+2i) ⇒ #f
These procedures return the sum or product of their arguments.
(+ 3 4) ⇒ 7 (+ 3) ⇒ 3 (+) ⇒ 0 (+ +inf.0 +inf.0) ⇒ +inf.0 (+ +inf.0 -inf.0) ⇒ +nan.0 (* 4) ⇒ 4 (*) ⇒ 1 (* 5 +inf.0) ⇒ +inf.0 (* -5 +inf.0) ⇒ -inf.0 (* +inf.0 +inf.0) ⇒ +inf.0 (* +inf.0 -inf.0) ⇒ -inf.0 (* 0 +inf.0) ⇒ +nan.0 (* 0 +nan.0) ⇒ +nan.0 (* 1.0 0) ⇒ 0.0For any real number object
x
that is neither infinite nor NaN:(+ +inf.0x
) ⇒ +inf.0 (+ -inf.0x
) ⇒ -inf.0For any real number object
x
:(+ +nan.0x
) ⇒ +nan.0For any real number object
x
that is not an exact 0:(* +nan.0x
) ⇒ +nan.0The behavior of
-0.0
is illustrated by the following examples:(+ 0.0 -0.0) ⇒ 0.0 (+ -0.0 0.0) ⇒ 0.0 (+ 0.0 0.0) ⇒ 0.0 (+ -0.0 -0.0) ⇒ -0.0
With two or more arguments, this procedures returns the difference of its arguments, associating to the left. With one argument, however, it returns the negation (additive inverse) of its argument.
(- 3 4) ⇒ -1 (- 3 4 5) ⇒ -6 (- 3) ⇒ -3 (- +inf.0 +inf.0) ⇒ +nan.0The behavior of
-0.0
is illustrated by the following examples:(- 0.0) ⇒ -0.0 (- -0.0) ⇒ 0.0 (- 0.0 -0.0) ⇒ 0.0 (- -0.0 0.0) ⇒ -0.0 (- 0.0 0.0) ⇒ 0.0 (- -0.0 -0.0) ⇒ 0.0
If all of the arguments are exact, then the divisors must all be nonzero. With two or more arguments, this procedure returns the quotient of its arguments, associating to the left. With one argument, however, it returns the multiplicative inverse of its argument.
(/ 3 4 5) ⇒ 3/20 (/ 3) ⇒ 1/3 (/ 0.0) ⇒ +inf.0 (/ 1.0 0) ⇒ +inf.0 (/ -1 0.0) ⇒ -inf.0 (/ +inf.0) ⇒ 0.0 (/ 0 0) ⇒ exception &assertion (/ 3 0) ⇒ exception &assertion (/ 0 3.5) ⇒ 0.0 (/ 0 0.0) ⇒ +nan.0 (/ 0.0 0) ⇒ +nan.0 (/ 0.0 0.0) ⇒ +nan.0If this procedure is applied to mixed non–rational real and non–real complex arguments, it either raises an exception with condition type
&implementation-restriction
or returns an unspecified number object.
These procedures implement number–theoretic integer division. They accept two real numbers
x
andy
as operands, wherey
must be nonzero. In all cases the result is two valuesq
(an integer) andr
(a real) that satisfy the equations:x
=q
*y
+r
q
=rounding-op
(x
/y
)The result is inexact if either argument is inexact.
For
floor/
therounding-op
is thefloor
function (below).(floor/ 123 10) ⇒ 12 3 (floor/ 123 -10) ⇒ -13 -7 (floor/ -123 10) ⇒ -13 7 (floor/ -123 -10) ⇒ 12 -3For
truncate/
therounding-op
is thetruncate
function.(truncate/ 123 10) ⇒ 12 3 (truncate/ 123 -10) ⇒ -12 3 (truncate/ -123 10) ⇒ -12 -3 (truncate/ -123 -10) ⇒ 12 -3For
div-and-mod
therounding-op
is eitherfloor
(ify
is positive) orceiling
(ify
is negative). We have:0 <=r
< |y
|(div-and-mod 123 10) ⇒ 12 3 (div-and-mod 123 -10) ⇒ -12 3 (div-and-mod -123 10) ⇒ -13 7 (div-and-mod -123 -10) ⇒ 13 7For
div0-and-mod0
therounding-op
is theround
function, andr
lies within a half–open interval centered on zero.-|y
/2| <=r
< |y
/2|(div0-and-mod0 123 10) ⇒ 12 3 (div0-and-mod0 123 -10) ⇒ -12 3 (div0-and-mod0 -123 10) ⇒ -12 -3 (div0-and-mod0 -123 -10) ⇒ 12 -3 (div0-and-mod0 127 10) ⇒ 13 -3 (div0-and-mod0 127 -10) ⇒ -13 -3 (div0-and-mod0 -127 10) ⇒ -13 3 (div0-and-mod0 -127 -10) ⇒ 13 3The inconsistent naming is for historical reasons:
div-and-mod
anddiv0-and-mod0
are from R6RS, whilefloor/
andtruncate/
are from R7RS.
These procedures return the quotient part (first value) of respectively
floor/
,truncate/
,div-and-mod
, anddiv0-and-mod0
.
These procedures return the remainder part (second value) of respectively
floor/
,truncate/
,div-and-mod
, anddiv0-and-mod0
.As a Kawa extension
y
may be zero, in which case the result isx
:(mod 123 0) ⇒ 123 ;; Kawa extension
These are equivalent to
truncate-quotient
,truncate-remainder
, andfloor-remainder
, respectively. These are provided for backward compatibility.(remainder 13 4) ⇒ 1 (remainder -13 4) ⇒ -1 (remainder 13 -4) ⇒ 1 (remainder -13 -4) ⇒ -1 (remainder -13 -4.0) ⇒ -1.0 (modulo 13 4) ⇒ 1 (modulo -13 4) ⇒ 3 (modulo 13 -4) ⇒ -4 (modulo -13 -4) ⇒ -1
These procedures return the greatest common divisor or least common multiple of their arguments. The result is always non–negative. (R6RS allows inexact integer arguments; Kawa does not.)
(gcd 32 -36) ⇒ 4 (gcd) ⇒ 0 (lcm 32 -36) ⇒ 288 (lcm 32.0 -36) ⇒ 288.0 (lcm) ⇒ 1
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 be1
. (R6RS allows inexact integer arguments; Kawa does not.)(numerator (/ 6 4)) ⇒ 3 (denominator (/ 6 4)) ⇒ 2
These procedures return inexact integer objects for inexact arguments that are not infinities or NaNs, and exact integer objects for exact rational arguments.
floor
Returns the largest integer object not larger than
x
.ceiling
Returns the smallest integer object not smaller than
x
.truncate
Returns the integer object closest to
x
whose absolute value is not larger than the absolute value ofx
.round
Returns the closest integer object to
x
, rounding to even whenx
represents a number halfway between two integers.If the argument to one of these procedures is inexact, then the result is also inexact. If an exact value is needed, the result should be passed to the
exact
procedure.Although infinities and NaNs are not integer objects, these procedures return an infinity when given an infinity as an argument, and a NaN when given a NaN.
(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 (round 7/2) ⇒ 4 (round 7) ⇒ 7 (floor +inf.0) ⇒ +inf.0 (ceiling -inf.0) ⇒ -inf.0 (round +nan.0) ⇒ +nan.0
The
rationalize
procedure returns a number object representing the simplest rational number differing fromx
_1 by no more thanx
_2.A rational number r_1 is simpler than another rational number r_2 if
r_1 = p_1/q_1
andr_2 = p_2/q_2
(in lowest terms) and|p_1| <= |p_2|
and|q_1| <= |q_2|
. Thus3/5
is simpler than4/7
.Although not all rationals are comparable in this ordering (consider
2/7
and3/5
) any interval contains a rational number that is simpler than every other rational number in that interval (the simpler2/5
lies between2/7
and3/5
).Note that
0 = 0/1
is the simplest rational of all.(rationalize (exact .3) 1/10) ⇒ 1/3 (rationalize .3 1/10) ⇒ #i1/3 ; approximately (rationalize +inf.0 3) ⇒ +inf.0 (rationalize +inf.0 +inf.0) ⇒ +nan.0The first two examples hold only in implementations whose inexact real number objects have sufficient precision.
These procedures compute the usual transcendental functions.
The
exp
procedure computes the base–e
exponential ofz
. Thelog
procedure with a single argument computes the natural logarithm ofz
(not the base–10 logarithm);(log
computes the base–z
_1z
_2)z
_2 logarithm ofz
_1.The
asin
,acos
, andatan
procedures compute arcsine, arccosine, and arctangent, respectively. The two–argument variant ofatan
computes:(angle (make-rectangularx
_2x
_1))These procedures may return inexact results even when given exact arguments.
(exp +inf.0) ⇒ +inf.0 (exp -inf.0) ⇒ 0.0 (log +inf.0) ⇒ +inf.0 (log 0.0) ⇒ -inf.0 (log 0) ⇒ exception &assertion (log -inf.0) ⇒ +inf.0+3.141592653589793i ; approximately (atan -inf.0) ⇒ -1.5707963267948965 ; approximately (atan +inf.0) ⇒ 1.5707963267948965 ; approximately (log -1.0+0.0i) ⇒ 0.0+3.141592653589793i ; approximately (log -1.0-0.0i) ⇒ 0.0-3.141592653589793i ; approximately ; if -0.0 is distinguished
Returns the square of
z
. This is equivalent to(*
.z
z
)(square 42) ⇒ 1764 (square 2.0) ⇒ 4.0
Return the principal square root of
z
. For rationalz
, the result has either positive real part, or zero real part and non–negative imaginary part. The value of(sqrt
could be expressed as:z
)e^((log z)/2)The
sqrt
procedure may return an inexact result even when given an exact argument.(sqrt -5) ⇒ 0.0+2.23606797749979i ; approximately (sqrt +inf.0) ⇒ +inf.0 (sqrt -inf.0) ⇒ +inf.0i
As a super-class of numbers, Kawa also provides quantities. A quantity is a product of a unit and a pure number. The number part can be an arbitrary complex number. The unit is a product of integer powers of base units, such as meter or second.
Quantity literals have the following syntax:
quantity
::=
optional-sign
decimal
unit-term
[*
unit-term
]... [/
unit-term
]
unit-term
::=
unit-name
[^
digit
+]
unit-name
::=
letter
+
Some examples are 10pt
(10 points), 5s
(5 seconds),
and 4cm^2
(4 square centimeters).
Note the quantity
syntax is not recognized by the reader.
Instead these are read as symbols.
Assuming there is no lexical binding the for the symbol, it will be
rewritten at compile-time into an expression. For example 4cm^2
is transformed into:
(* 4.0 (expt unit:cm 2))
True iff
object
is a quantity. Note that all numbers are quantities, but not the other way round. Currently, there are no quantities that re not numbers. To distinguish a plain unit-less number from a quantity, you can usecomplex?
.
Returns the pure number part of the quantity
q
, relative to primitive (base) units. Ifq
is a number, returnsq
. Ifq
is a unit, yields the magitude ofq
relative to base units.
Returns the product of
x
(a pure number) andunit
. You can specify a string instead ofunit
, such as"cm"
or"s"
(seconds).
These functions operate on the 2's complement binary representation of an exact integer.
Returns the bit-wise logical inverse of the argument. More formally, returns the exact integer whose two's complement representation is the one's complement of the two's complement representation of
i
.
These procedures return the exact integer that is the bit-wise “and”, “inclusive or”, or “exclusive or” of the two's complement representations of their arguments. If they are passed only one argument, they return that argument. If they are passed no arguments, they return the integer that acts as identity for the operation: -1, 0, or 0, respectively.
Returns the exact integer that is the bit-wise “if” of the twos complement representations of its arguments, i.e. for each bit, if it is 1 in i1, the corresponding bit in i2 becomes the value of the corresponding bit in the result, and if it is 0, the corresponding bit in i3 becomes the corresponding bit in the value of the result. This is equivaent to the following computation:
(bitwise-ior (bitwise-and i1 i2) (bitwise-and (bitwise-not i1) i3))
If ei is non-negative, returns the number of 1 bits in the twos complement representation of i. Otherwise it returns the result of the following computation:
(bitwise-not (bitwise-bit-count (bitwise-not i)))
Returns the number of bits needed to represent i if it is positive, and the number of bits needed to represent
(bitwise-not
if it is negative, which is the exact integer that is the result of the following computation:i
)(do ((result 0 (+ result 1)) (bits (if (negative? i) (bitwise-not i) ei) (bitwise-arithmetic-shift bits -1))) ((zero? bits) result))This is the number of bits needed to represent
i
in an unsigned field.
Returns the index of the least significant 1 bit in the twos complement representation of i. If ei is 0, then - 1 is returned.
(bitwise-first-bit-set 0) ⇒ -1 (bitwise-first-bit-set 1) ⇒ 0 (bitwise-first-bit-set -4) ⇒ 2
Returns
#t
if the i2'th bit (wherei2
must be non-negative) is 1 in the two's complement representation ofi1
, and#f
otherwise. This is the result of the following computation:(not (zero? (bitwise-and (bitwise-arithmetic-shift-left 1 i2) i1)))
bitwise-copy-bit
i
bitno
replacement-bit
Return the result of replacing the
bitno
'th bit ofi
byreplacement-bit
, wherebitno
must be non-negative, andreplacement-bit
must be either 0 or 1. This is the result of the following computation:(let* ((mask (bitwise-arithmetic-shift-left 1 bitno))) (bitwise-if mask (bitwise-arithmetic-shift-left replacement-bit bitno) i))
Return the integer formed from the (unsigned) bit-field starting at
start
and ending just beforeend
. Same as:(let ((mask (bitwise-not (bitwise-arithmetic-shift-left -1end
)))) (bitwise-arithmetic-shift-right (bitwise-andn
mask)start
))
bitwise-copy-bit-field
to
start
end
from
Returns the result of replacing in
to
the bits at positions fromstart
(inclusive) toend
(exclusive) by the bits infrom
from position 0 (inclusive) to positionend
-start
(exclusive). Bothstart
andstart
must be non-negative, andstart
must be less than or equal tostart
.This is the result of the following computation:
(let* ((mask1 (bitwise-arithmetic-shift-left -1 start)) (mask2 (bitwise-not (bitwise-arithmetic-shift-left -1 end))) (mask (bitwise-and mask1 mask2))) (bitwise-if mask (bitwise-arithmetic-shift-left from start) to))
Shifts
i
byj
. It is a “left” shift if, and a “right” shift if
j
>0. The result is equal to
j
<0(floor (*
.i
(expt 2j
)))Examples:
(bitwise-arithmetic-shift -6 -1) ⇒-3 (bitwise-arithmetic-shift -5 -1) ⇒ -3 (bitwise-arithmetic-shift -4 -1) ⇒ -2 (bitwise-arithmetic-shift -3 -1) ⇒ -2 (bitwise-arithmetic-shift -2 -1) ⇒ -1 (bitwise-arithmetic-shift -1 -1) ⇒ -1
bitwise-arithmetic-shift-left
i
amount
bitwise-arithmetic-shift-right
i
amount
The
amount
must be non-negative Thebitwise-arithmetic-shift-left
procedure returns the same result asbitwise-arithmetic-shift
, and(bitwise-arithmetic-shift-right
returns the same result asi
amount
)(bitwise-arithmetic-shift
;i
(-amount
))
bitwise-rotate-bit-field
n
start
end
count
Returns the result of cyclically permuting in
n
the bits at positions fromstart
(inclusive) toend
(exclusive) bycount
bits towards the more significant bits,start
andend
must be non-negative, andstart
must be less than or equal toend
. This is the result of the following computation:(let* ((n ei1) (width (- end start))) (if (positive? width) (let* ((count (mod count width)) (field0 (bitwise-bit-field n start end)) (field1 (bitwise-arithmetic-shift-left field0 count)) (field2 (bitwise-arithmetic-shift-right field0 (- width count))) (field (bitwise-ior field1 field2))) (bitwise-copy-bit-field n start end field)) n))
bitwise-reverse-bit-field
i
start
end
Returns the result obtained from
i
by reversing the order of the bits at positions fromstart
(inclusive) toend
(exclusive), wherestart
andend
must be non-negative, andstart
must be less than or equal toend
.(bitwise-reverse-bit-field #b1010010 1 4) ⇒ 88 ; #b1011000
Returns true if the arguments have any bits in common. Same as
(not (zero? (bitwise-and
, but is more efficient.i
j
)))
Kawa supports SRFI-60 “Integers as Bits” as well, although we
generally recommend using the R6RS-compatible functions instead when
possible. Unless noted as being a builtin function, to use these you
must first (require 'srfi-60)
or (import (srfi :60))
(or (import (srfi :60 integer-bits))
).
Count the number of 1-bits in
i
, if it is non-negative. Ifi
is negative, count number of 0-bits. Same as(bitwise-bit-count
ifi
)i
is non-negative. Builtin aslogcount
.
The
integer->list
procedure returns a list oflength
booleans corresponding to the bits of the non-negative integerk
, with#t
for1
and#f
for0
.length
defaults to(bitwise-length
. The list will be in order from MSB to LSB, with the value ofk
)(odd?
in the last car.k
)The
list->integer
procedure returns the integer corresponding to the booleans in the listlist
. Theinteger->list
andlist->integer
procedures are inverses so far asequal?
is concerned.
Kawa can generally do a pretty good job of generating efficient code for numeric operations, at least when it knows or can figure out the types of the operands.
The basic operations +
, -
, and *
are compiled to single-instruction bytecode if both
operands are int
or long
.
Likewise, if both operands are floating-point (or
one is floating-point and the other is rational),
then single-instruction double
or float
instructions are emitted.
A binary operation involing an infinite-precision integer
and a fixed-size int
or long
is normally
evaluated by expanding the latter to integer
and using integer
arithmetic. An exception is the
integer
argument is an integer literal whose
value fits in a int
or long
- in that case
the operation is done using int
or long
arithmetic.
In general, integer literals have amorphous type.
When used to infer the type of a variable, they have integer
type:
(let ((v1 0)) ... v1 has type integer ... )
However, a literal whose value fits in the int
or long
range
is implicitly viewed int
or long
in certain contexts,
primarily method overload resolution and binary arithmethic
(as mentioned above).
The comparison functions <
, <=
, =
,
>
, and =>
are also optimized to single instriction
operations if the operands have appropriate type.
However, the functions zero?
, positive?
, and negative?
have not yet been optimized.
Instead of (positive? x)
write (> x 0)
.
There are a number of integer division and modulo operations.
If the operands are int
or long
, it is faster
to use quotient
and remainder
rather
than div
and mod
(or modulo
).
If you know the first operand is non-negative and the second is positive,
then use quotient
and remainder
.
(If an operand is an arbitrary-precision integer
,
then it dosn't really matter.)
The logical operations bitwise-and
, bitwise-ior
,
bitwise-xor
, bitwise-not
, bitwise-arithmetic-shift-left
,
bitwise-arithmetic-shift-right
are compiled
to single bitcode instructions if the operands are int
or long
.
Avoid bitwise-arithmetic-shift
if the sign of the shift is known.
If the operands are arbitrary-precision integer
,
a library call is needed, but run-time type dispatch is avoided.