]> gitweb.factorcode.org Git - factor.git/blob - core/math/math-docs.factor
Initial import
[factor.git] / core / math / math-docs.factor
1 USING: help.markup help.syntax kernel sequences quotations
2 math.private math.functions ;
3 IN: math
4
5 ARTICLE: "division-by-zero" "Division by zero"
6 "Floating point division never raises an error if the denominator is zero. This means that if at least one of the two inputs to " { $link / } ", " { $link /f } " or " { $link mod } " is a float, the result will be a floating point infinity or not a number value."
7 $nl
8 "The behavior of integer division is hardware specific. On x86 processors, " { $link /i } " and " { $link mod } " raise an error if both inputs are integers and the denominator is zero. On PowerPC, integer division by zero yields a result of zero."
9 $nl
10 "On the other hand, the " { $link / } " word, when given integer arguments, implements a much more expensive division algorithm which always yields an exact rational answer, and this word always tests for division by zero explicitly." ;
11
12 ARTICLE: "number-protocol" "Number protocol"
13 "Math operations obey certain numerical upgrade rules. If one of the inputs is a bignum and the other is a fixnum, the latter is first coerced to a bignum; if one of the inputs is a float, the other is coerced to a float."
14 $nl
15 "Two examples where you should note the types of the inputs and outputs:"
16 { $example "3 >fixnum 6 >bignum * class ." "bignum" }
17 { $example "1/2 2.0 + ." "4.5" }
18 "The following usual operations are supported by all numbers."
19 { $subsection + }
20 { $subsection - }
21 { $subsection * }
22 { $subsection / }
23 "Non-commutative operations take operands from the stack in the natural order; " { $snippet "6 2 /" } " divides 6 by 2."
24 { $subsection "division-by-zero" }
25 "Real numbers (but not complex numbers) can be ordered:"
26 { $subsection < }
27 { $subsection <= }
28 { $subsection > }
29 { $subsection >= }
30 "Inexact comparison:"
31 { $subsection ~ } ;
32
33 ARTICLE: "modular-arithmetic" "Modular arithmetic"
34 { $subsection mod }
35 { $subsection rem }
36 { $subsection /mod }
37 { $subsection /i }
38 { $subsection mod-inv }
39 { $subsection ^mod }
40 { $see-also "integer-functions" } ;
41
42 ARTICLE: "bitwise-arithmetic" "Bitwise arithmetic"
43 "There are two ways of looking at an integer -- as an abstract mathematical entity, or as a string of bits. The latter representation motivates " { $emphasis "bitwise operations" } "."
44 { $subsection bitand }
45 { $subsection bitor }
46 { $subsection bitxor }
47 { $subsection bitnot }
48 { $subsection shift }
49 { $subsection 2/ }
50 { $subsection 2^ }
51 { $subsection bit? }
52 { $see-also "conditionals" } ;
53
54 ARTICLE: "arithmetic" "Arithmetic"
55 "Factor attempts to preserve natural mathematical semantics for numbers. Multiplying two large integers never results in overflow, and dividing two integers yields an exact ratio. Floating point numbers are also supported, along with complex numbers."
56 $nl
57 "Math words are in the " { $vocab-link "math" } " vocabulary. Implementation details are in the " { $vocab-link "math.private" } " vocabulary."
58 { $subsection "number-protocol" }
59 { $subsection "modular-arithmetic" }
60 { $subsection "bitwise-arithmetic" }
61 { $see-also "integers" "rationals" "floats" "complex-numbers" } ;
62
63 ABOUT: "arithmetic"
64
65 HELP: number=
66 { $values { "x" number } { "y" number } { "?" "a boolean" } }
67 { $description "Tests if two numbers have the same numerical value. If either input is not a number, outputs " { $link f } "." }
68 { $notes "Do not call this word directly. Calling " { $link = } " has the same effect and is more concise." } ;
69
70 HELP: <
71 { $values { "x" real } { "y" real } { "?" "a boolean" } }
72 { $description "Tests if " { $snippet "x" } " is less than " { $snippet "y" } "." } ;
73
74 HELP: <=
75 { $values { "x" real } { "y" real } { "?" "a boolean" } }
76 { $description "Tests if " { $snippet "x" } " is less than or equal to " { $snippet "y" } "." } ;
77
78 HELP: >
79 { $values { "x" real } { "y" real } { "?" "a boolean" } }
80 { $description "Tests if " { $snippet "x" } " is greater than " { $snippet "y" } "." } ;
81
82 HELP: >=
83 { $values { "x" real } { "y" real } { "?" "a boolean" } }
84 { $description "Tests if " { $snippet "x" } " is greater than or equal to " { $snippet "y" } "." } ;
85
86 HELP: +
87 { $values { "x" number } { "y" number } { "z" number } }
88 { $description
89     "Adds two numbers."
90     { $list
91         "Addition of fixnums may overflow and convert the result to a bignum."
92         "Addition of bignums always yields a bignum."
93         "Addition of floats always yields a float."
94         "Addition of ratios and complex numbers proceeds using the relevant mathematical rules."
95     }
96 } ;
97
98 HELP: -
99 { $values { "x" number } { "y" number } { "z" number } }
100 { $description
101     "Subtracts " { $snippet "y" } " from " { $snippet "x" } "."
102     { $list
103         "Subtraction of fixnums may overflow and convert the result to a bignum."
104         "Subtraction of bignums always yields a bignum."
105         "Subtraction of floats always yields a float."
106         "Subtraction of ratios and complex numbers proceeds using the relevant mathematical rules."
107     }
108 } ;
109
110 HELP: *
111 { $values { "x" number } { "y" number } { "z" number } }
112 { $description
113     "Multiplies two numbers."
114     { $list
115         "Multiplication of fixnums may overflow and convert the result to a bignum."
116         "Multiplication of bignums always yields a bignum."
117         "Multiplication of floats always yields a float."
118         "Multiplication of ratios and complex numbers proceeds using the relevant mathematical rules."
119     }
120 } ;
121
122 HELP: /
123 { $values { "x" number } { "y" number } { "z" number } }
124 { $description
125     "Divides " { $snippet "x" } " by " { $snippet "y" } ", retaining as much precision as possible."
126     { $list
127         "Division of fixnums may yield a ratio, or overflow and yield a bignum."
128         "Division of bignums may yield a ratio."
129         "Division of floats always yields a float."
130         "Division of ratios and complex numbers proceeds using the relevant mathematical rules."
131     }
132 }
133 { $see-also "division-by-zero" } ;
134
135 HELP: /i
136 { $values { "x" real } { "y" real } { "z" real } }
137 { $description
138     "Divides " { $snippet "x" } " by " { $snippet "y" } ", truncating the result to an integer."
139     { $list
140         "Integer division of fixnums may overflow and yield a bignum."
141         "Integer division of bignums always yields a bignum."
142         "Integer division of floats always yields a float."
143         "Integer division of ratios and complex numbers proceeds using the relevant mathematical rules."
144     }
145 }
146 { $see-also "division-by-zero" } ;
147
148 HELP: /f
149 { $values { "x" real } { "y" real } { "z" real } }
150 { $description
151     "Divides " { $snippet "x" } " by " { $snippet "y" } ", representing the result as a floating point number."
152     { $list 
153         "Integer division of fixnums may overflow and yield a bignum."
154         "Integer division of bignums always yields a bignum."            
155         "Integer division of floats always yields a float."
156         "Integer division of ratios and complex numbers proceeds using the relevant mathematical rules."
157     }
158 }
159 { $see-also "division-by-zero" } ;
160
161 HELP: mod
162 { $values { "x" integer } { "y" integer } { "z" integer } }
163 { $description
164     "Computes the remainder of dividing " { $snippet "x" } " by " { $snippet "y" } ", with the remainder being negative if " { $snippet "x" } " is negative."
165     { $list 
166         "Modulus of fixnums always yields a fixnum."
167         "Modulus of bignums always yields a bignum."            
168     }
169 }
170 { $see-also "division-by-zero" rem } ;
171
172 HELP: /mod
173 { $values { "x" integer } { "y" integer } { "z" integer } { "w" integer } }
174 { $description
175     "Computes the quotient " { $snippet "z" } " and remainder " { $snippet "w" } " of dividing " { $snippet "x" } " by " { $snippet "y" } ", with the remainder being negative if " { $snippet "x" } " is negative."
176     { $list 
177         "The quotient of two fixnums may overflow and yield a bignum; the remainder is always a fixnum"
178         "The quotient and remainder of two bignums is always a bignum."            
179     }
180 }
181 { $see-also "division-by-zero" } ;
182
183 HELP: bitand
184 { $values { "x" integer } { "y" integer } { "z" integer } }
185 { $description "Outputs a new integer where each bit is set if and only if the corresponding bit is set in both inputs." }
186 { $examples
187     { $example "BIN: 101 BIN: 10 bitand .b" "0" }
188     { $example "BIN: 110 BIN: 10 bitand .b" "10" }
189 }
190 { $notes "This word implements bitwise and, so applying it to booleans will throw an error. Boolean and is the " { $link and } " word." } ;
191
192 HELP: bitor
193 { $values { "x" integer } { "y" integer } { "z" integer } }
194 { $description "Outputs a new integer where each bit is set if and only if the corresponding bit is set in at least one of the inputs." }
195 { $examples
196     { $example "BIN: 101 BIN: 10 bitor .b" "111" }
197     { $example "BIN: 110 BIN: 10 bitor .b" "110" }
198 }
199 { $notes "This word implements bitwise inclusive or, so applying it to booleans will throw an error. Boolean inclusive or is the " { $link and } " word." } ;
200
201 HELP: bitxor
202 { $values { "x" integer } { "y" integer } { "z" integer } }
203 { $description "Outputs a new integer where each bit is set if and only if the corresponding bit is set in exactly one of the inputs." }
204 { $examples
205     { $example "BIN: 101 BIN: 10 bitxor .b" "111" }
206     { $example "BIN: 110 BIN: 10 bitxor .b" "100" }
207 }
208 { $notes "This word implements bitwise exclusive or, so applying it to booleans will throw an error. Boolean exclusive or is the " { $link xor } " word." } ;
209
210 HELP: shift
211 { $values { "x" integer } { "n" integer } { "y" integer } }
212 { $description "Shifts " { $snippet "x" } " to the left by " { $snippet "y" } " bits if " { $snippet "y" } " is positive, or " { $snippet "-y" } " bits to the right if " { $snippet "y" } " is negative. A left shift of a fixnum may overflow, yielding a bignum. A right shift may result in bits ``falling off'' the right hand side and being discarded." }
213 { $examples { $example "BIN: 101 5 shift .b" "10100000" } { $example "BIN: 11111 -2 shift .b" "111" } } ;
214
215 HELP: bitnot
216 { $values { "x" integer } { "y" integer } }
217 { $description "Computes the bitwise complement of the input; that is, each bit in the input number is flipped." }
218 { $notes "This word implements bitwise not, so applying it to booleans will throw an error. Boolean not is the " { $link not } " word."
219 $nl
220 "Due to the two's complement representation of signed integers, the following two lines are equivalent:" { $code "bitnot" "neg 1-" } } ;
221
222 HELP: bit?
223 { $values { "x" integer } { "n" integer } { "?" "a boolean" } }
224 { $description "Tests if the " { $snippet "n" } "th bit of " { $snippet "x" } " is set." }
225 { $examples { $example "BIN: 101 3 bit? ." "t" } } ;
226
227 HELP: log2
228 { $values { "n" "a positive integer" } { "b" integer } }
229 { $description "Outputs the largest integer " { $snippet "b" } " such that " { $snippet "2^b" } " is less than " { $snippet "n" } "." }
230 { $errors "Throws an error if " { $snippet "n" } " is zero or negative." } ;
231
232 HELP: 1+
233 { $values { "x" number } { "y" number } }
234 { $description
235     "Increments a number by 1. The following two lines are equivalent, but the first is more efficient:"
236     { $code "1+" "1 +" }
237 } ;
238
239 HELP: 1-
240 { $values { "x" number } { "y" number } }
241 { $description
242     "Decrements a number by 1. The following two lines are equivalent, but the first is more efficient:"
243     { $code "1-" "1 -" }
244 } ;
245
246 HELP: truncate
247 { $values { "x" real } { "y" "a whole real number" } }
248 { $description "Outputs the number that results from subtracting the fractional component of " { $snippet "x" } "." }
249 { $notes "The result is not necessarily an integer." } ;
250
251 HELP: floor
252 { $values { "x" real } { "y" "a whole real number" } }
253 { $description "Outputs the greatest whole number smaller than or equal to " { $snippet "x" } "." }
254 { $notes "The result is not necessarily an integer." } ;
255
256 HELP: ceiling
257 { $values { "x" real } { "y" "a whole real number" } }
258 { $description "Outputs the least whole number greater than or equal to " { $snippet "x" } "." }
259 { $notes "The result is not necessarily an integer." } ;
260
261 HELP: round
262 { $values { "x" real } { "y" "a whole real number" } }
263 { $description "Outputs the whole number closest to " { $snippet "x" } "." }
264 { $notes "The result is not necessarily an integer." } ;
265
266 HELP: sq
267 { $values { "x" number } { "y" number } }
268 { $description "Multiplies a number by itself." } ;
269
270 HELP: neg
271 { $values { "x" number } { "-x" number } }
272 { $description "Computes a number's additive inverse." } ;
273
274 HELP: recip
275 { $values { "x" number } { "y" number } }
276 { $description "Computes a number's multiplicative inverse." }
277 { $errors "Throws an error if " { $snippet "x" } " is the integer 0." } ;
278
279 HELP: max
280 { $values { "x" real } { "y" real } { "z" real } }
281 { $description "Outputs the greatest of two real numbers." } ;
282
283 HELP: min
284 { $values { "x" real } { "y" real } { "z" real } }
285 { $description "Outputs the smallest of two real numbers." } ;
286
287 HELP: between?
288 { $values { "x" real } { "y" real } { "z" real } { "?" "a boolean" } }
289 { $description "Tests if " { $snippet "x" } " is in the interval " { $snippet "[y,z]" } "." }
290 { $notes "As per the closed interval notation, the end-points are included in the interval." } ;
291
292 HELP: rem
293 { $values { "x" integer } { "y" integer } { "z" integer } }
294 { $description
295     "Computes the remainder of dividing " { $snippet "x" } " by " { $snippet "y" } ", with the remainder always positive."
296     { $list 
297         "Modulus of fixnums always yields a fixnum."
298         "Modulus of bignums always yields a bignum."            
299     }
300 }
301 { $see-also "division-by-zero" mod } ;
302
303 HELP: sgn
304 { $values { "x" real } { "n" "-1, 0 or 1" } }
305 { $description
306     "Outputs one of the following:"
307     { $list
308         "-1 if " { $snippet "x" } " is negative"
309         "0 if " { $snippet "x" } " is equal to 0"
310         "1 if " { $snippet "x" } " is positive"
311     }
312 } ;
313
314 HELP: 2/
315 { $values { "x" integer } { "y" integer } }
316 { $description "Shifts " { $snippet "x" } " to the right by one bit." }
317 { $examples
318     { $example "14 2/ ." "7" }
319     { $example "17 2/ ." "8" }
320     { $example "-17 2/ ." "-9" }
321 }
322 { $notes "This word is not equivalent to " { $snippet "2 /" } " or " { $snippet "2 /i" } "; the name is historic and originates from the Forth programming language." } ;
323
324 HELP: 2^
325 { $values { "n" "a positive integer" } { "2^n" "a positive integer" } }
326 { $description "Computes two to the power of " { $snippet "n" } ". This word will only give correct results if " { $snippet "n" } " is greater than zero; for the general case, use " { $snippet  "2 swap ^" } "." } ;
327
328 HELP: zero?
329 { $values { "x" number } { "?" "a boolean" } }
330 { $description "Tests if the number is equal to zero." } ;
331
332 HELP: times
333 { $values { "n" integer } { "quot" quotation } }
334 { $description "Calls the quotation " { $snippet "n" } " times." }
335 { $notes "If you need to pass the current index to the quotation, use " { $link each } "." } ;
336
337 HELP: [-]
338 { $values { "x" real } { "y" real } { "z" real } }
339 { $description "Subtracts " { $snippet "y" } " from " { $snippet "x" } ". If the result is less than zero, outputs zero." } ;
340
341 HELP: fp-nan?
342 { $values { "x" real } { "?" "a boolean" } }
343 { $description "Tests if " { $snippet "x" } " is an IEEE Not-a-Number value. While " { $snippet "x" } " can be any real number, this word will only ever yield true if " { $snippet "x" } " is a " { $link float } "." } ;
344
345 HELP: real ( z -- x )
346 { $values { "z" number } { "x" real } }
347 { $description "Outputs the real part of a complex number. This acts as the identity on real numbers." }
348 { $class-description "The class of real numbers, which is a disjoint union of rationals and floats." } ;
349
350 HELP: imaginary ( z -- y )
351 { $values { "z" number } { "y" real } }
352 { $description "Outputs the imaginary part of a complex number. This outputs zero for real numbers." } ;
353
354 HELP: (rect>)
355 { $values { "x" real } { "y" real } { "z" number } }
356 { $description "Creates a complex number from real and imaginary components." }
357 { $warning "This word does not check that the arguments are real numbers, which can have undefined consequences. Use the " { $link rect> } " word instead." } ;
358
359 HELP: number
360 { $class-description "The class of numbers." } ;
361
362 HELP: rect>
363 { $values { "x" real } { "y" real } { "z" number } }
364 { $description "Creates a complex number from real and imaginary components." } ;
365
366 HELP: >rect
367 { $values { "z" number } { "x" real } { "y" real } }
368 { $description "Extracts the real and imaginary components of a complex number." } ;
369
370 HELP: next-power-of-2
371 { $values { "m" "a non-negative integer" } { "n" "an integer" } }
372 { $description "Outputs the smallest power of 2 greater than " { $snippet "m" } ". The output value is always at least 1." } ;
373
374 HELP: each-integer
375 { $values { "n" integer } { "quot" "a quotation with stack effect " { $snippet "( i -- )" } } }
376 { $description "Applies the quotation to each integer from 0 up to " { $snippet "n" } ", excluding " { $snippet "n" } "." }
377 { $notes "This word is used to implement " { $link each } "." } ;
378
379 HELP: all-integers?
380 { $values { "n" integer } { "quot" "a quotation with stack effect " { $snippet "( i -- ? )" } } { "i" "an integer or " { $link f } } }
381 { $description "Applies the quotation to each integer from 0 up to " { $snippet "n" } ", excluding " { $snippet "n" } ". Iterationi stops when the quotation outputs " { $link f } " or the end is reached. If the quotation yields a false value for some integer, this word outputs " { $link f } ". Otherwise, this word outputs " { $link t } "." }
382 { $notes "This word is used to implement " { $link all? } "." } ;
383
384 HELP: find-integer
385 { $values { "n" integer } { "quot" "a quotation with stack effect " { $snippet "( i -- ? )" } } { "i" "an integer or " { $link f } } }
386 { $description "Applies the quotation to each integer from 0 up to " { $snippet "n" } ", excluding " { $snippet "n" } ". Iterationi stops when the quotation outputs a true value or the end is reached. If the quotation yields a true value for some integer, this word outputs that integer. Otherwise, this word outputs " { $link f } "." }
387 { $notes "This word is used to implement " { $link find } "." } ;
388
389 HELP: find-last-integer
390 { $values { "n" integer } { "quot" "a quotation with stack effect " { $snippet "( i -- ? )" } } { "i" "an integer or " { $link f } } }
391 { $description "Applies the quotation to each integer from " { $snippet "n" } " down to 0, inclusive. Iteration stops when the quotation outputs a true value or 0 is reached. If the quotation yields a true value for some integer, the word outputs that integer. Otherwise, the word outputs " { $link f } "." }
392 { $notes "This word is used to implement " { $link find-last } "." } ;