source: project/wiki/eggref/5/srfi-144 @ 40042

Last change on this file since 40042 was 40042, checked in by Diego, 2 months ago

Add docs for srfi-144

File size: 18.8 KB
Line 
1[[tags: egg]]
2
3[[toc:]]
4
5== SRFI 144: Flonums
6
7=== Abstract
8
9This SRFI describes numeric procedures applicable to flonums, a subset of the
10inexact real numbers provided by a Scheme implementation. In most Schemes, the
11flonums and the inexact reals are the same. These procedures are semantically
12equivalent to the corresponding generic procedures, but allow more efficient
13implementations.
14
15=== Rationale
16
17Flonum arithmetic is already supported by many systems, mainly to remove
18type-dispatching overhead. Standardizing flonum arithmetic increases the
19portability of code that uses it. Standardizing the range or precision of
20flonums would make flonum operations inefficient on some systems, which would
21defeat their purpose. Therefore, this SRFI specifies some of the semantics of
22flonums, but makes the range and precision implementation-dependent. However,
23this SRFI, unlike C99, does assume that the floating-point radix is 2.
24
25The source of most of the variables and procedures in this SRFI is the
26C99/Posix {{<math.h>}} library, which should be available directly or
27indirectly to Scheme implementers. (Note: the C90 version of {{<math.h>}} lacks
28{{arcsinh}}, {{arccosh}}, {{arctanh}}, {{erf}}, and {{tgamma}}.)
29
30In addition, some procedures and variables are provided from the R6RS flonum
31library, the Chicken flonum routines, and the Chicken mathh egg. Lastly, a few
32procedures are flonum versions of R7RS-small numeric procedures.
33
34The SRFI text is by John Cowan; the portable implementation is by Will Clinger.
35
36=== Specification
37
38It is required that all flonums have the same range and precision. That is, if
39{{12.0f0}} is a 32-bit inexact number and 12.0 is a 64-bit inexact number, they
40cannot both be flonums. In this situation, it is recommended that the 64-bit
41numbers be flonums.
42
43When a C99 variable, procedure, macro, or operator is specified for a procedure
44in this SRFI, the semantics of the Scheme variable or procedure are the same as
45its C equivalent. The definitions given here of such procedures are informative
46only; for precise definitions, users and implementers must consult the Posix or
47C99 standards. This applies particularly to the behavior of these procedures on
48{{-0.0}}, {{+inf.0}}, {{-inf.0}}, and {{+nan.0}}. However, conformance to this
49SRFI does not require that these numbers exist or are flonums.
50
51When a variable is bound to, or a procedure returns, a mathematical expression,
52it is understood that the value is the best flonum approximation to the
53mathematically correct value.
54
55It is an error, except as otherwise noted, for an argument not to be a flonum.
56If the mathematically correct result is not a real number, the result is
57{{+nan.0}} if the implementation supports that number, or an arbitrary flonum
58if not.
59
60Flonum operations must be at least as accurate as their generic counterparts
61when applied to flonum arguments. In some cases, operations should be more
62accurate than their naive generic expansions because they have a smaller total
63roundoff error.
64
65This SRFI uses {{x}}, {{y}}, {{z}} as parameter names for flonum arguments.
66Exact integer parameters are designated {{n}}.
67
68==== Mathematical Constants
69
70The following (mostly C99) constants are provided as Scheme variables.
71
72<constant>fl-e</constant>
73
74Bound to the mathematical constant ''e''. (C99 {{M_E}})
75
76<constant>fl-1/e</constant>
77
78Bound to 1/''e''. (C99 {{M_E}})
79
80<constant>fl-e-2</constant>
81
82Bound to ''e''^2.
83
84<constant>fl-e-pi/4</constant>
85
86Bound to ''e''^(π/4).
87
88<constant>fl-log2-e</constant>
89
90Bound to log2(''e''). (C99 {{M_LOG2E}})
91
92<constant>fl-log10-e</constant>
93
94Bound to log10(''e''). (C99 {{M_LOG10E}})
95
96<constant>fl-log-2</constant>
97
98Bound to ln(2). (C99 {{M_LN2}})
99
100<constant>fl-1/log-2</constant>
101
102Bound to 1/ln(2). (C99 {{M_LN2}})
103
104<constant>fl-log-3</constant>
105
106Bound to ln(3).
107
108<constant>fl-log-pi</constant>
109
110Bound to ln(π).
111
112<constant>fl-log-10</constant>
113
114Bound to ln(10). (C99 {{M_LN10}})
115
116<constant>fl-1/log-10</constant>
117
118Bound to 1/ln(10). (C99 {{M_LN10}})
119
120<constant>fl-pi</constant>
121
122Bound to the mathematical constant π. (C99 {{M_PI}})
123
124<constant>fl-1/pi</constant>
125
126Bound to 1/π. (C99 M_1_PI)
127
128<constant>fl-2pi</constant>
129
130Bound to 2π.
131
132<constant>fl-pi/2</constant>
133
134Bound to π/2. (C99 {{M_PI_2}})
135
136<constant>fl-pi/4</constant>
137
138Bound to π/4. (C99 {{M_PI_4}})
139
140<constant>fl-pi-squared</constant>
141
142Bound to π^2.
143
144<constant>fl-degree</constant>
145
146Bound to π/180, the number of radians in a degree.
147
148<constant>fl-2/pi</constant>
149
150Bound to 2/π. (C99 {{M_2_PI}})
151
152<constant>fl-2/sqrt-pi</constant>
153
154Bound to 2/√π. (C99 {{M_2_SQRTPI}})
155
156<constant>fl-sqrt-2</constant>
157
158Bound to √2. (C99 {{M_SQRT2}})
159
160<constant>fl-sqrt-3</constant>
161
162Bound to √3.
163
164<constant>fl-sqrt-5</constant>
165
166Bound to √5.
167
168<constant>fl-sqrt-10</constant>
169
170Bound to √10.
171
172<constant>fl-1/sqrt-2</constant>
173
174Bound to 1/√2. (C99 {{M_SQRT1_2}})
175
176<constant>fl-cbrt-2</constant>
177
178Bound to ∛2.
179
180<constant>fl-cbrt-3</constant>
181
182Bound to ∛3.
183
184<constant>fl-4thrt-2</constant>
185
186Bound to ∜2.
187
188<constant>fl-phi</constant>
189
190Bound to the mathematical constant φ.
191
192<constant>fl-log-phi</constant>
193
194Bound to log(φ).
195
196<constant>fl-1/log-phi</constant>
197
198Bound to 1/log(φ).
199
200<constant>fl-euler</constant>
201
202Bound to the mathematical constant γ (Euler's constant).
203
204<constant>fl-e-euler</constant>
205
206Bound to ''e''^γ.
207
208<constant>fl-sin-1</constant>
209
210Bound to sin(1).
211
212<constant>fl-cos-1</constant>
213
214Bound to cos(1).
215
216<constant>fl-gamma-1/2</constant>
217
218Bound to Γ(1/2).
219
220<constant>fl-gamma-1/3</constant>
221
222Bound to Γ(1/3).
223
224<constant>fl-gamma-2/3</constant>
225
226Bound to Γ(2/3).
227
228==== Implementation Constants
229
230<constant>fl-greatest</constant>
231
232<constant>fl-least</constant>
233
234Bound to the largest/smallest positive finite flonum. (e.g. C99 {{DBL_MAX}} and
235C11 {{DBL_TRUE_MIN}})
236
237<constant>fl-epsilon</constant>
238
239Bound to the appropriate machine epsilon for the hardware representation of
240flonums. (C99 {{DBL_EPSILON}} in {{<float.h>}})
241
242<constant>fl-fast-fl+*</constant>
243
244Bound to #t if {{(fl+* x y z)}} executes about as fast as, or faster than,
245{{(fl+ (fl* x y) z)}}; bound to #f otherwise. (C99 {{FP_FAST_FMA}})
246
247So that the value of this variable can be determined at compile time, R7RS
248implementations and other implementations that provide a features function
249should provide the feature {{fl-fast-fl+*}} if this variable is true, and not
250if it is false or the value is unknown at compile time.
251
252<constant>fl-integer-exponent-zero</constant>
253
254Bound to whatever exact integer is returned by {{(flinteger-exponent 0.0)}}.
255(C99 {{FP_ILOGB0}})
256
257<constant>fl-integer-exponent-nan</constant>
258
259Bound to whatever exact integer is returned by {{(flinteger-exponent +nan.0)}}.
260(C99 {{FP_ILOGBNAN}})
261
262==== Constructors
263
264<procedure>(flonum number)</procedure>
265
266If number is an inexact real number and there exists a flonum that is the same
267(in the sense of {{=}}) to number, returns that flonum. If number is a negative
268zero, an infinity, or a NaN, return its flonum equivalent. If such a flonum
269does not exist, returns the nearest flonum, where "nearest" is
270implementation-dependent. If number is not a real number, it is an error. If
271number is exact, applies inexact or {{exact->inexact}} to number first.
272
273<procedure>(fladjacent x y)</procedure>
274
275Returns a flonum adjacent to {{x}} in the direction of {{y}}. Specifically: if
276{{x < y}}, returns the smallest flonum larger than {{x}}; if {{x > y}}, returns
277the largest flonum smaller than {{x}}; if {{x = y}}, returns {{x}}. (C99
278{{nextafter}})
279
280<procedure>(flcopysign x y)</procedure>
281
282Returns a flonum whose magnitude is the magnitude of {{x}} and whose sign is the
283sign of {{y}}. (C99 {{copysign}})
284
285<procedure>(make-flonum x n)</procedure>
286
287Returns {{x × 2n}}, where {{n}} is an integer with an implementation-dependent
288range. (C99 {{ldexp}})
289
290==== Accessors
291
292<procedure>(flinteger-fraction x)</procedure>
293
294Returns two values, the integral part of {{x}} as a flonum and the fractional
295part of {{x}} as a flonum. (C99 {{modf}})
296
297<procedure>(flexponent x)</procedure>
298
299Returns the exponent of {{x}}. (C99 {{logb}})
300
301<procedure>(flinteger-exponent x)</procedure>
302
303Returns the same as flexponent truncated to an exact integer. If {{x}} is zero,
304returns {{fl-integer-exponent-zero}}; if {{x}} is a NaN, returns
305{{fl-integer-exponent-nan}}; if {{x}} is infinite, returns a large
306implementation-dependent exact integer. (C99 {{ilogb}})
307
308<procedure>(flnormalized-fraction-exponent x)</procedure>
309
310Returns two values, a correctly signed fraction {{y}} whose absolute value is
311between 0.5 (inclusive) and 1.0 (exclusive), and an exact integer exponent
312{{n}} such that {{x = y(2^n)}}. (C99 {{frexp}})
313
314<procedure>(flsign-bit x)</procedure>
315
316Returns 0 for positive flonums and 1 for negative flonums and -0.0. The value
317of {{(flsign-bit +nan.0)}} is implementation-dependent, reflecting the sign bit
318of the underlying representation of NaNs. (C99 {{signbit}})
319
320==== Predicates
321
322<procedure>(flonum? obj)</procedure>
323
324Returns #t if obj is a flonum and #f otherwise.
325
326<procedure>(fl=? x y z ...)</procedure>
327<procedure>(fl<? x y z ...)</procedure>
328<procedure>(fl>? x y z ...)</procedure>
329<procedure>(fl<=? x y z ...)</procedure>
330<procedure>(fl>=? x y z ...)</procedure>
331
332These procedures return {{#t}} if their arguments are (respectively): equal,
333monotonically increasing, monotonically decreasing, monotonically
334nondecreasing, or monotonically nonincreasing; they return {{#f}} otherwise. These
335predicates must be transitive. (C99 {{=}}, {{<}}, {{>}}, {{<=}}, {{>=}}
336operators respectively)
337
338<procedure>(flunordered? x y)</procedure>
339
340Returns {{#t}} if {{x}} and {{y}} are unordered according to IEEE rules. This
341means that one of them is a NaN.
342
343These numerical predicates test a flonum for a particular property, returning
344{{#t}} or {{#f}}.
345
346<procedure>(flinteger? x)</procedure>
347
348Tests whether {{x}} is an integral flonum.
349
350<procedure>(flzero? x)</procedure>
351
352Tests whether {{x}} is zero. Beware of roundoff errors.
353
354<procedure>(flpositive? x)</procedure>
355
356Tests whether {{x}} is positive.
357
358<procedure>(flnegative? x)</procedure>
359
360Tests whether {{x}} is negative. Note that {{(flnegative? -0.0)}} must return
361{{#f}}; otherwise it would lose the correspondence with {{(fl<? -0.0 0.0)}},
362which is {{#f}} according to IEEE 754.
363
364<procedure>(flodd? x)</procedure>
365
366Tests whether the flonum {{x}} is odd. It is an error if {{x}} is not an
367integer.
368
369<procedure>(fleven? x)</procedure>
370
371Tests whether the flonum {{x}} is even. It is an error if {{x}} is not an
372integer.
373
374<procedure>(flfinite? x)</procedure>
375
376Tests whether the flonum {{x}} is finite. (C99 {{isfinite}})
377
378<procedure>(flinfinite? x)</procedure>
379
380Tests whether the flonum {{x}} is infinite. (C99 {{isinf}})
381
382<procedure>(flnan? x)</procedure>
383
384Tests whether the flonum {{x}} is NaN. (C99 {{isnan}})
385
386<procedure>(flnormalized? x)</procedure>
387
388Tests whether the flonum {{x}} is normalized. (C11 {{isnormal}}; in C99, use
389{{fpclassify(x) == FP_NORMAL}})
390
391<procedure>(fldenormalized? x)</procedure>
392
393Tests whether the flonum {{x}} is denormalized. (C11 {{issubnormal}}; in C99,
394use {{fpclassify(x) == FP_SUBNORMAL}})
395
396==== Arithmetic
397
398<procedure>(flmax x ...)</procedure>
399<procedure>(flmin x ...)</procedure>
400
401Return the maximum/minimum argument. If there are no arguments, these
402procedures return {{-inf.0}} or {{+inf.0}} if the implementation provides these
403numbers, and {{(fl- fl-greatest)}} or {{fl-greatest}} otherwise. (C99 {{fmax}}
404{{fmin}})
405
406<procedure>(fl+ x ...)</procedure>
407<procedure>(fl* x ...)</procedure>
408
409Return the flonum sum or product of their flonum arguments. (C99 {{+}} {{*}}
410operators respectively)
411
412<procedure>(fl+* x y z)</procedure>
413
414Returns {{xy + z}} as if to infinite precision and rounded only once. The
415boolean constant {{fl-fast-fl+*}} indicates whether this procedure executes
416about as fast as, or faster than, a multiply and an add of flonums. (C99
417{{fma}})
418
419<procedure>(fl- x y ...)</procedure>
420<procedure>(fl/ x y ...)</procedure>
421
422With two or more arguments, these procedures return the difference or quotient
423of their arguments, associating to the left. With one argument, however, they
424return the additive or multiplicative inverse of their argument. (C99 {{-}}
425{{/}} operators respectively)
426
427<procedure>(flabs x)</procedure>
428
429Returns the absolute value of {{x}}. (C99 {{fabs}})
430
431<procedure>(flabsdiff x y)</procedure>
432
433Returns {{|x - y|}}.
434
435<procedure>(flposdiff x y)</procedure>
436
437Returns the difference of {{x}} and {{y}} if it is non-negative, or zero if the
438difference is negative. (C99 {{fdim}})
439
440<procedure>(flsgn x)</procedure>
441
442Returns {{(flcopysign 1.0 x)}}.
443
444<procedure>(flnumerator x)</procedure>
445<procedure>(fldenominator x)</procedure>
446
447Returns the numerator/denominator of {{x}} as a flonum; the result is computed
448as if {{x}} was represented as a fraction in lowest terms. The denominator is
449always positive. The numerator of an infinite flonum is itself. The denominator
450of an infinite or zero flonum is 1.0. The numerator and denominator of a NaN is
451a NaN.
452
453<procedure>(flfloor x)</procedure>
454
455Returns the largest integral flonum not larger than {{x}}. (C99 {{floor}})
456
457<procedure>(flceiling x)</procedure>
458
459Returns the smallest integral flonum not smaller than {{x}}. (C99 {{ceil}})
460
461<procedure>(flround x)</procedure>
462
463Returns the closest integral flonum to {{x}}, rounding to even when {{x}}
464represents a number halfway between two integers. (Not the same as C99
465{{round}}, which rounds away from zero)
466
467<procedure>(fltruncate x)</procedure>
468
469Returns the closest integral flonum to {{x}} whose absolute value is not larger
470than the absolute value of {{x}} (C99 {{trunc}})
471
472==== Exponents and logarithms
473
474<procedure>(flexp x)</procedure>
475
476Returns ''e''^{{x}}. (C99 exp)
477
478<procedure>(flexp2 x)</procedure>
479
480Returns 2{{x}}. (C99 exp2)
481
482<procedure>(flexp-1 x)</procedure>
483
484Returns ''e''^{{x}} - 1, but is much more accurate than {{flexp}} for very
485small values of {{x}}. It is recommended for use in algorithms where accuracy
486is important. (C99 {{expm1}})
487
488<procedure>(flsquare x)</procedure>
489
490Returns {{x}}^2.
491
492<procedure>(flsqrt x)</procedure>
493
494Returns √{{x}}. For -0.0, {{flsqrt}} should return -0.0. (C99 {{sqrt}})
495
496<procedure>(flcbrt x)</procedure>
497
498Returns ∛{{x}}. (C99 cbrt)
499
500<procedure>(flhypot x y)</procedure>
501
502Returns the length of the hypotenuse of a right triangle whose sides are of
503length |{{x}}| and |{{y}}|. (C99 {{hypot}})
504
505<procedure>(flexpt x y)</procedure>
506
507Returns {{x}}^{{y}}. If {{x}} is zero, then the result is zero. (C99 {{pow}})
508
509<procedure>(fllog x)</procedure>
510
511Returns ln({{x}}). (C99 {{log}})
512
513<procedure>(fllog1+ x)</procedure>
514
515Returns ln({{x}} + 1), but is much more accurate than fllog for values of {{x}}
516near 0. It is recommended for use in algorithms where accuracy is important.
517(C99 {{log1p}})
518
519<procedure>(fllog2 x)</procedure>
520
521Returns log2({{x}}). (C99 {{log2}})
522
523<procedure>(fllog10 x)</procedure>
524
525Returns log10({{x}}). (C99 {{log10}})
526
527<procedure>(make-fllog-base x)</procedure>
528
529Returns a procedure that calculates the base-{{x}} logarithm of its argument.
530If {{x}} is 1.0 or less than 1.0, it is an error.
531
532=== Trigonometric functions
533
534<procedure>(flsin x)</procedure>
535
536Returns sin({{x}}). (C99 {{sin}})
537
538<procedure>(flcos x)</procedure>
539
540Returns cos({{x}}). (C99 {{cos}})
541
542<procedure>(fltan x)</procedure>
543
544Returns tan({{x}}). (C99 {{tan}})
545
546<procedure>(flasin x)</procedure>
547
548Returns arcsin({{x}}). (C99 {{asin}})
549
550<procedure>(flacos x)</procedure>
551
552Returns arccos({{x}}). (C99 {{acos}})
553
554<procedure>(flatan [y] x)</procedure>
555
556Returns arctan({{x}}). (C99 {{atan}})
557
558With two arguments, returns arctan({{y}}/{{x}}) in the range [-π,π], using the
559signs of {{x}} and {{y}} to choose the correct quadrant for the result. (C99
560{{atan2}})
561
562<procedure>(flsinh x)</procedure>
563
564Returns sinh({{x}}). (C99 {{sinh}})
565
566<procedure>(flcosh x)</procedure>
567
568Returns cosh({{x}}). (C99 {{cosh}})
569
570<procedure>(fltanh x)</procedure>
571
572Returns tanh({{x}}). (C99 {{tanh}})
573
574<procedure>(flasinh x)</procedure>
575
576Returns arcsinh({{x}}). (C99 {{asinh}})
577
578<procedure>(flacosh x)</procedure>
579
580Returns arccosh({{x}}). (C99 {{acosh}})
581
582<procedure>(flatanh x)</procedure>
583
584Returns arctanh({{x}}). (C99 {{atanh}})
585
586==== Integer division
587
588<procedure>(flquotient x y)</procedure>
589
590Returns the quotient of {{x}}/{{y}} as an integral flonum, truncated towards zero.
591
592<procedure>(flremainder x y)</procedure>
593
594Returns the truncating remainder of {{x}}/{{y}} as an integral flonum.
595
596<procedure>(flremquo x y)</procedure>
597
598Returns two values, the rounded remainder of {{x}}/{{y}} and the low-order
599{{n}} bits (as a correctly signed exact integer) of the rounded quotient. The
600value of {{n}} is implementation-dependent but at least 3. This procedure can
601be used to reduce the argument of the inverse trigonometric functions, while
602preserving the correct quadrant or octant. (C99 {{remquo}})
603
604==== Special functions
605
606<procedure>(flgamma x)</procedure>
607
608Returns Γ({{x}}), the gamma function applied to {{x}}. This is equal to
609({{x}}-1)! for integers. (C99 {{tgamma}})
610
611<procedure>(flloggamma x)</procedure>
612
613Returns two values, log |Γ({{x}})| without internal overflow, and the sign of
614Γ({{x}}) as 1.0 if it is positive and -1.0 if it is negative. (C99 {{lgamma}})
615
616<procedure>(flfirst-bessel n x)</procedure>
617
618Returns the {{n}}th order Bessel function of the first kind applied to {{x}},
619Jn({{x}}). ({{jn}}, which is an XSI Extension of C99)
620
621<procedure>(flsecond-bessel n x)</procedure>
622
623Returns the {{n}}th order Bessel function of the second kind applied to {{x}},
624Yn({{x}}). ({{yn}}, which is an XSI Extension of C99)
625
626<procedure>(flerf x)</procedure>
627
628Returns the error function erf({{x}}). (C99 {{erf}})
629
630<procedure>(flerfc x)</procedure>
631
632Returns the complementary error function, 1 - erf({{x}}). (C99 {{erfc}})
633
634=== Acknowledgements
635
636This SRFI would not have been possible without Taylor Campbell, the R6RS
637editors, and the ISO C Working Group.
638
639=== Author
640
641John Cowan, Will Clinger
642
643=== Maintainer
644
645[[/users/diego-mundo|Diego A. Mundo]]
646
647=== Repository
648
649[[https://code.dieggsy.com/srfi-144]]
650
651=== Copyright
652
653 Copyright (C) John Cowan (2016). All Rights Reserved.
654 
655 Permission is hereby granted, free of charge, to any person obtaining a copy of
656 this software and associated documentation files (the "Software"), to deal in
657 the Software without restriction, including without limitation the rights to
658 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
659 of the Software, and to permit persons to whom the Software is furnished to do
660 so, subject to the following conditions:
661 
662 The above copyright notice and this permission notice shall be included in all
663 copies or substantial portions of the Software.
664 
665 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
666 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
667 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
668 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
669 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
670 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
671 SOFTWARE. Editor: Arthur A. Gleckler
Note: See TracBrowser for help on using the repository browser.