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#tif 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#tif 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
#tifzis both exact and an integer; otherwise returns#f.(exact-integer? 32) ⇒ #t (exact-integer? 32.0) ⇒ #t (exact-integer? 32/5) ⇒ #f
Returns
#tifzis finite real number (i.e. an infinity and not a NaN), or ifzis 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
#tifzis an infinite real number (+int.0or-inf.0), or ifzis 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
xthat 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
xthat is not an exact 0:(* +nan.0x) ⇒ +nan.0The behavior of
-0.0is 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.0is 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-restrictionor returns an unspecified number object.
These procedures implement number–theoretic integer division. They accept two real numbers
xandyas operands, whereymust be nonzero. In all cases the result is two valuesq(an integer) andr(a real) that satisfy the equations:x=q*y+rq=rounding-op(x/y)The result is inexact if either argument is inexact.
For
floor/therounding-opis thefloorfunction (below).(floor/ 123 10) ⇒ 12 3 (floor/ 123 -10) ⇒ -13 -7 (floor/ -123 10) ⇒ -13 7 (floor/ -123 -10) ⇒ 12 -3For
truncate/therounding-opis thetruncatefunction.(truncate/ 123 10) ⇒ 12 3 (truncate/ 123 -10) ⇒ -12 3 (truncate/ -123 10) ⇒ -12 -3 (truncate/ -123 -10) ⇒ 12 -3For
div-and-modtherounding-opis eitherfloor(ifyis positive) orceiling(ifyis 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-mod0therounding-opis theroundfunction, andrlies 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-modanddiv0-and-mod0are 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
ymay 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
0is 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.
floorReturns the largest integer object not larger than
x.ceilingReturns the smallest integer object not smaller than
x.truncateReturns the integer object closest to
xwhose absolute value is not larger than the absolute value ofx.roundReturns the closest integer object to
x, rounding to even whenxrepresents 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
exactprocedure.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
rationalizeprocedure 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_1andr_2 = p_2/q_2(in lowest terms) and|p_1| <= |p_2|and|q_1| <= |q_2|. Thus3/5is simpler than4/7.Although not all rationals are comparable in this ordering (consider
2/7and3/5) any interval contains a rational number that is simpler than every other rational number in that interval (the simpler2/5lies between2/7and3/5).Note that
0 = 0/1is 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
expprocedure computes the base–eexponential ofz. Thelogprocedure with a single argument computes the natural logarithm ofz(not the base–10 logarithm);(logcomputes the base–z_1z_2)z_2 logarithm ofz_1.The
asin,acos, andatanprocedures compute arcsine, arccosine, and arctangent, respectively. The two–argument variant ofatancomputes:(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(*.zz)(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(sqrtcould be expressed as:z)e^((log z)/2)The
sqrtprocedure 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
objectis 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. Ifqis a number, returnsq. Ifqis a unit, yields the magitude ofqrelative 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-notif 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
iin 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
#tif the i2'th bit (wherei2must be non-negative) is 1 in the two's complement representation ofi1, and#fotherwise. 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 ofibyreplacement-bit, wherebitnomust be non-negative, andreplacement-bitmust 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
startand ending just beforeend. Same as:(let ((mask (bitwise-not (bitwise-arithmetic-shift-left -1end)))) (bitwise-arithmetic-shift-right (bitwise-andnmask)start))
bitwise-copy-bit-field to start end from
Returns the result of replacing in
tothe bits at positions fromstart(inclusive) toend(exclusive) by the bits infromfrom position 0 (inclusive) to positionend-start(exclusive). Bothstartandstartmust be non-negative, andstartmust 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
ibyj. It is a “left” shift if, and a “right” shift ifj>0. The result is equal toj<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
amountmust be non-negative Thebitwise-arithmetic-shift-leftprocedure returns the same result asbitwise-arithmetic-shift, and(bitwise-arithmetic-shift-rightreturns the same result asiamount)(bitwise-arithmetic-shift;i(-amount))
bitwise-rotate-bit-field n start end count
Returns the result of cyclically permuting in
nthe bits at positions fromstart(inclusive) toend(exclusive) bycountbits towards the more significant bits,startandendmust be non-negative, andstartmust 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
iby reversing the order of the bits at positions fromstart(inclusive) toend(exclusive), wherestartandendmust be non-negative, andstartmust 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.ij)))
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. Ifiis negative, count number of 0-bits. Same as(bitwise-bit-countifi)iis non-negative. Builtin aslogcount.
The
integer->listprocedure returns a list oflengthbooleans corresponding to the bits of the non-negative integerk, with#tfor1and#ffor0.lengthdefaults 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->integerprocedure returns the integer corresponding to the booleans in the listlist. Theinteger->listandlist->integerprocedures 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.
