1 (define-module (language python module decimal
)
2 #:use-module
((language python module collections
) #:select
(namedtuple))
3 #:use-module
((language python module itertools
) #:select
(chain repeat
))
4 #:use-module
((language python module sys
) #:select
(maxsize hash_info
))
5 #:use-module
(language python module
)
6 #:use-module
((language python module python
) #:select
7 (isinstance str float int tuple classmethod pow property
8 complex range reversed
(format . str-format
)))
9 #:use-module
(language python list
)
10 #:use-module
(language python number
)
11 #:use-module
(language python string
)
12 #:use-module
(language python for
)
13 #:use-module
(language python try
)
14 #:use-module
(language python hash
)
15 #:use-module
(language python dict
)
16 #:use-module
(language python def
)
17 #:use-module
(language python exceptions
)
18 #:use-module
(language python bool
)
19 #:use-module
(language python module
)
20 #:use-module
(oop pf-objects
)
21 #:use-module
(oop goops
)
22 #:use-module
(language python module re
)
23 #:use-module
(ice-9 control
)
24 #:use-module
((ice-9 match
) #:select
((match . ice
:match
)))
26 ( ;; Two major classes
29 ;; Named tuple representation
33 DefaultContext BasicContext ExtendedContext
36 DecimalException Clamped InvalidOperation DivisionByZero
37 Inexact Rounded Subnormal Overflow Underflow
40 ;; Exceptional conditions that trigger InvalidOperation
41 DivisionImpossible InvalidContext ConversionSyntax DivisionUndefined
43 ;; Constants for use in setting up contexts
44 ROUND_DOWN ROUND_HALF_UP ROUND_HALF_EVEN ROUND_CEILING
45 ROUND_FLOOR ROUND_UP ROUND_HALF_DOWN ROUND_05UP
47 ;; Functions for manipulating contexts
48 setcontext getcontext localcontext
50 ;; Limits for the C version for compatibility
51 MAX_PREC MAX_EMAX MIN_EMIN MIN_ETINY
))
53 (define-syntax-rule (aif it p . l
) (let ((it p
)) (if it . l
)))
56 This is the copyright information of the file ported over to scheme
57 # Copyright
(c) 2004 Python Software Foundation.
58 # All rights reserved.
60 # Written by Eric Price
<eprice at tjhsst.edu
>
61 # and Facundo Batista
<facundo at taniquetil.com.ar
>
62 # and Raymond Hettinger
<python at rcn.com
>
63 # and Aahz
<aahz at pobox.com
>
66 # This module should be kept in sync with the latest updates of the
67 # IBM specification as it evolves. Those updates will be treated
68 # as bug fixes
(deviation from the spec is a compatibility
, usability
69 # bug
) and will be backported. At this point the spec is stabilizing
70 # and the updates are becoming fewer
, smaller
, and less significant.
73 (define guile
:modulo
(@ (guile) modulo
))
75 (define __name__
"decimal")
76 (define __xname__ __name__
)
77 (define __version__
"1.70")
78 ;; Highest version of the spec this complies with
79 ;; See http://speleotrove.com/decimal/
81 (define DecimalTuple
(namedtuple "DecimalTuple" "sign,digits,exponent"))
84 (define ROUND_DOWN
'ROUND_DOWN
)
85 (define ROUND_HALF_UP
'ROUND_HALF_UP
)
86 (define ROUND_HALF_EVEN
'ROUND_HALF_EVEN
)
87 (define ROUND_CEILING
'ROUND_CEILING
)
88 (define ROUND_FLOOR
'ROUND_FLOOR
)
89 (define ROUND_UP
'ROUND_UP
)
90 (define ROUND_HALF_DOWN
'ROUND_HALF_DOWN
)
91 (define ROUND_05UP
'ROUND_05UP
)
93 ;; Compatibility with the C version
94 (define MAX_PREC
425000000)
95 (define MAX_EMAX
425000000)
96 (define MIN_EMIN -
425000000)
98 (if (= maxsize
(- (ash 1 63) 1))
100 (set! MAX_PREC
999999999999999999)
101 (set! MAX_EMAX
999999999999999999)
102 (set! MIN_EMIN -
999999999999999999)))
104 (define MIN_ETINY
(- MIN_EMIN
(- MAX_PREC
1)))
107 (define-inlinable (cx-prec x
) (rawref x
'prec
))
108 (define-inlinable (cx-emax x
) (rawref x
'Emax
))
109 (define-inlinable (cx-emin x
) (rawref x
'Emin
))
110 (define-inlinable (cx-etiny x
) ((ref x
'Etiny
)))
111 (define-inlinable (cx-etop x
) ((ref x
'Etop
)))
112 (define-inlinable (cx-copy x
) ((ref x
'copy
)))
113 (define-inlinable (cx-clear_flags x
) ((ref x
'clear_flags
)))
114 (define-inlinable (cx-raise x
) (ref x
'_raise_error
))
115 (define-inlinable (cx-error x
) (ref x
'_raise_error
))
116 (define-inlinable (cx-capitals x
) (rawref x
'capitals
))
117 (define-inlinable (cx-cap x
) (rawref x
'capitals
))
118 (define-inlinable (cx-rounding x
) (rawref x
'rounding
))
119 (define-inlinable (cx-clamp x
) (rawref x
'clamp
))
120 (define-inlinable (cx-traps x
) (rawref x
'traps
))
121 (define-inlinable (cx-flags x
) (rawref x
'flags
))
125 (define-python-class DecimalException
(ArithmeticError)
126 "Base exception class.
128 Used exceptions derive from this.
129 If an exception derives from another exception besides this (such as
130 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
131 called if the others are present. This isn't actually used for
134 handle -- Called when context._raise_error is called and the
135 trap_enabler is not set. First argument is self, second is the
136 context. More arguments can be given, those being after
137 the explanation in _raise_error (For example,
138 context._raise_error(NewError, '(-x)!', self._sign) would
139 call NewError().handle(context, self._sign).)
141 To define a new exception, it should be sufficient to have it derive
142 from DecimalException.
146 (lambda (self context . args
)
150 (define-python-class Clamped
(DecimalException)
151 "Exponent of a 0 changed to fit bounds.
153 This occurs and signals clamped if the exponent of a result has been
154 altered in order to fit the constraints of a specific concrete
155 representation. This may occur when the exponent of a zero result would
156 be outside the bounds of a representation, or when a large normal
157 number would have an encoded exponent that cannot be represented. In
158 this latter case, the exponent is reduced to fit and the corresponding
159 number of zero digits are appended to the coefficient ('fold-down').
162 (define-python-class InvalidOperation
(DecimalException)
163 "An invalid operation was performed.
165 Various bad things cause this:
167 Something creates a signaling NaN
173 x._rescale( non-integer )
178 An operand is invalid
180 The result of the operation after these is a quiet positive NaN,
181 except when the cause is a signaling NaN, in which case the result is
182 also a quiet NaN, but with the original sign, and an optional
183 diagnostic information.
186 (lambda (self context . args
)
188 (let ((ans (_dec_from_triple
189 (ref (car args
) '_sign
)
190 (ref (car args
) '_int
)
192 ((ref ans
'_fix_nan
) context
))
195 (define-python-class ConversionSyntax
(InvalidOperation)
196 "Trying to convert badly formed string.
198 This occurs and signals invalid-operation if a string is being
199 converted to a number and it does not conform to the numeric string
200 syntax. The result is [0,qNaN].
205 (define-python-class DivisionByZero
(DecimalException ZeroDivisionError
)
208 This occurs and signals division-by-zero if division of a finite number
209 by zero was attempted (during a divide-integer or divide operation, or a
210 power operation with negative right-hand operand), and the dividend was
213 The result of the operation is [sign,inf], where sign is the exclusive
214 or of the signs of the operands for divide, or is 1 for an odd power of
219 (lambda (self context sign . args
)
220 (pylist-ref _SignedInfinity sign
))))
222 (define-python-class DivisionImpossible
(InvalidOperation)
223 "Cannot perform the division adequately.
225 This occurs and signals invalid-operation if the integer result of a
226 divide-integer or remainder operation had too many digits (would be
227 longer than precision). The result is [0,qNaN].
233 (define-python-class DivisionUndefined
(InvalidOperation ZeroDivisionError
)
234 "Undefined result of division.
236 This occurs and signals invalid-operation if division by zero was
237 attempted (during a divide-integer, divide, or remainder operation), and
238 the dividend is also zero. The result is [0,qNaN].
244 (define-python-class Inexact
(DecimalException)
245 "Had to round, losing information.
247 This occurs and signals inexact whenever the result of an operation is
248 not exact (that is, it needed to be rounded and any discarded digits
249 were non-zero), or if an overflow or underflow condition occurs. The
250 result in all cases is unchanged.
252 The inexact signal may be tested (or trapped) to determine if a given
253 operation (or sequence of operations) was inexact.
256 (define-python-class InvalidContext
(InvalidOperation)
257 "Invalid context. Unknown rounding, for example.
259 This occurs and signals invalid-operation if an invalid context was
260 detected during an operation. This can occur if contexts are not checked
261 on creation and either the precision exceeds the capability of the
262 underlying concrete representation or an unknown or unsupported rounding
263 was specified. These aspects of the context need only be checked when
264 the values are required to be used. The result is [0,qNaN].
270 (define-python-class Rounded
(DecimalException)
271 "Number got rounded (not necessarily changed during rounding).
273 This occurs and signals rounded whenever the result of an operation is
274 rounded (that is, some zero or non-zero digits were discarded from the
275 coefficient), or if an overflow or underflow condition occurs. The
276 result in all cases is unchanged.
278 The rounded signal may be tested (or trapped) to determine if a given
279 operation (or sequence of operations) caused a loss of precision.
282 (define-python-class Subnormal
(DecimalException)
283 "Exponent < Emin before rounding.
285 This occurs and signals subnormal whenever the result of a conversion or
286 operation is subnormal (that is, its adjusted exponent is less than
287 Emin, before any rounding). The result in all cases is unchanged.
289 The subnormal signal may be tested (or trapped) to determine if a given
290 or operation (or sequence of operations) yielded a subnormal result.
293 (define-python-class Overflow
(Inexact Rounded
)
296 This occurs and signals overflow if the adjusted exponent of a result
297 (from a conversion or from an operation that is not an attempt to divide
298 by zero), after rounding, would be greater than the largest value that
299 can be handled by the implementation (the value Emax).
301 The result depends on the rounding mode:
303 For round-half-up and round-half-even (and for round-half-down and
304 round-up, if implemented), the result of the operation is [sign,inf],
305 where sign is the sign of the intermediate result. For round-down, the
306 result is the largest finite number that can be represented in the
307 current precision, with the sign of the intermediate result. For
308 round-ceiling, the result is the same as for round-down if the sign of
309 the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
310 the result is the same as for round-down if the sign of the intermediate
311 result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
316 (let ((l (list ROUND_HALF_UP ROUND_HALF_EVEN
317 ROUND_HALF_DOWN ROUND_UP
)))
318 (lambda (self context sign . args
)
320 (if (memq (ref context
'rounding
) l
)
321 (ret (pylist-ref _SignedInfinity sign
)))
324 (if (eq?
(ref context
'rounding
) ROUND_CEILING
)
325 (ret (pylist-ref _SignedInfinity sign
))
326 (ret (_dec_from_triple
328 (* "9" (cx-prec context
))
329 (+ (- (cx-emax context
) (cx-prec context
)) 1)))))
332 (if (eq?
(ref context
'rounding
) ROUND_FLOOR
)
333 (ret (pylist-ref _SignedInfinity sign
))
334 (ret (_dec_from_triple
336 (* "9" (cx-prec context
))
337 (+ (- (cx-emax context
) (cx-prec context
)) 1))))))))))
340 (define-python-class Underflow
(Inexact Rounded Subnormal
)
341 "Numerical underflow with result rounded to 0.
343 This occurs and signals underflow if a result is inexact and the
344 adjusted exponent of the result would be smaller (more negative) than
345 the smallest value that can be handled by the implementation (the value
346 Emin). That is, the result is both inexact and subnormal.
348 The result after an underflow will be a subnormal number rounded, if
349 necessary, so that its exponent is not less than Etiny. This may result
350 in 0 with the sign of the intermediate result and an exponent of Etiny.
352 In all cases, Inexact, Rounded, and Subnormal will also be raised.
355 (define-python-class FloatOperation
(DecimalException TypeError
)
356 "Enable stricter semantics for mixing floats and Decimals.
358 If the signal is not trapped (default), mixing floats and Decimals is
359 permitted in the Decimal() constructor, context.create_decimal() and
360 all comparison operators. Both conversion and comparisons are exact.
361 Any occurrence of a mixed operation is silently recorded by setting
362 FloatOperation in the context flags. Explicit conversions with
363 Decimal.from_float() or context.create_decimal_from_float() do not
366 Otherwise (the signal is trapped), only equality comparisons and explicit
367 conversions are silent. All other mixed operations raise FloatOperation.
370 ;; List of public traps and flags
372 (list Clamped DivisionByZero Inexact Overflow Rounded
373 Underflow InvalidOperation Subnormal FloatOperation
))
375 ;; Map conditions (per the spec) to signals
376 (define _condition_map
378 `((,ConversionSyntax .
,InvalidOperation
)
379 (,DivisionImpossible .
,InvalidOperation
)
380 (,DivisionUndefined .
,InvalidOperation
)
381 (,InvalidContext .
,InvalidOperation
))))
383 ;; Valid rounding modes
384 (define _rounding_modes
385 (list ROUND_DOWN ROUND_HALF_UP ROUND_HALF_EVEN ROUND_CEILING
386 ROUND_FLOOR ROUND_UP ROUND_HALF_DOWN ROUND_05UP
))
388 ;; ##### Context Functions ##################################################
390 ;; The getcontext() and setcontext() function manage access to a thread-local
392 (define *context
* (make-fluid #f
))
394 (fluid-ref *context
*))
395 (define (setcontext context
)
396 (fluid-set! *context
* context
))
398 ;; ##### Decimal class #######################################################
400 ;; Do not subclass Decimal from numbers.Real and do not register it as such
401 ;; (because Decimals are not interoperable with floats). See the notes in
402 ;; numbers.py for more detail.
404 (define _dec_from_triple
405 (lam (sign coefficient exponent
(= special
#f
))
406 "Create a decimal instance directly, without any validation,
407 normalization (e.g. removal of leading zeros) or argument
410 This function is for *internal use only*.
412 (Decimal sign coefficient exponent special
)))
414 (define (get-parsed-sign m
)
415 (if (equal?
((ref m
'group
) "sign") "-")
419 (define (get-parsed-int m
)
420 ((ref m
'group
) "int"))
422 (define (get-parsed-frac m
)
423 (let ((r ((ref m
'group
) "frac")))
428 (define (get-parsed-exp m
)
429 (let ((r ((ref m
'group
) "exp")))
432 (string->number r
))))
434 (define (get-parsed-diag m
)
435 ((ref m
'group
) "diag"))
437 (define (get-parsed-sig m
)
438 ((ref m
'group
) "signal"))
440 (def (_mk self __init__
(= value
"0") (= context None
))
441 "Create a decimal point instance.
443 >>> Decimal('3.14') # string input
445 >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent)
447 >>> Decimal(314) # int
449 >>> Decimal(Decimal(314)) # another decimal instance
451 >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay
455 ;; Note that the coefficient, self._int, is actually stored as
456 ;; a string rather than as a tuple of digits. This speeds up
457 ;; the "digits to integer" and "integer to digits" conversions
458 ;; that are used in almost every arithmetic operation on
459 ;; Decimals. This is an internal detail: the as_tuple function
460 ;; and the Decimal constructor still deal with tuples of
464 ;; REs insist on real strings, so we can too.
466 ((isinstance value str
)
467 (let ((m (_parser (scm-str value
))))
469 (let ((context (if (eq? context None
)
474 (+ "Invalid literal for Decimal: " value
))))
476 (let ((sign (get-parsed-sign m
))
477 (intpart (get-parsed-int m
))
478 (fracpart (get-parsed-frac m
))
479 (exp (get-parsed-exp m
))
480 (diag (get-parsed-diag m
))
481 (signal (get-parsed-sig m
)))
483 (set self
'_sign sign
)
485 (if (not (eq? intpart None
))
487 (set self
'_int
(str (int (+ intpart fracpart
))))
488 (set self
'_exp
(- exp
(len fracpart
)))
489 (set self
'_is_special
#f
))
491 (if (not (eq? diag None
))
495 (py-lstrip (str (int (if (bool diag
)
501 (set self
'_exp
'n
)))
505 (set self
'_exp
'F
)))
506 (set self
'_is_special
#t
))))))
509 ((isinstance value int
)
514 (set self
'_int
(str (abs value
)))
515 (set self
'_is_special
#f
))
517 ;; From another decimal
518 ((isinstance value Decimal
)
519 (set self
'_exp
(ref value
'_exp
))
520 (set self
'_sign
(ref value
'_sign
))
521 (set self
'_int
(ref value
'_int
))
522 (set self
'_is_special
(ref value
'_is_special
)))
524 ;; From an internal working value
525 ((isinstance value _WorkRep
)
526 (set self
'_exp
(int (ref value
'_exp
)))
527 (set self
'_sign
(ref value
'_sign
))
528 (set self
'_int
(str (ref value
'int
)))
529 (set self
'_is_special
#f
))
531 ;; tuple/list conversion (possibly from as_tuple())
532 ((isinstance value
(list list tuple
))
533 (if (not (= (len value
) 3))
535 (+ "Invalid tuple size in creation of Decimal "
536 "from list or tuple. The list or tuple "
537 "should have exactly three elements."))))
538 ;; # process sign. The isinstance test rejects floats
539 (let ((v0 (pylist-ref value
0))
540 (v1 (pylist-ref value
1))
541 (v2 (pylist-ref value
2)))
542 (if (not (and (isinstance v0 int
)
543 (or (= v0
0) (= v0
1))))
545 (+ "Invalid sign. The first value in the tuple "
546 "should be an integer; either 0 for a "
547 "positive number or 1 for a negative number."))))
553 (set self
'is_special
#t
))
554 (let ((digits (py-list)))
555 ;; process and validate the digits in value[1]
556 (for ((digit : v1
)) ()
557 (if (and (isinstance digit int
)
560 ;; skip leading zeros
561 (if (or (bool digits
) (> digit
0))
562 (pylist-append! digits digit
))
564 (+ "The second value in the tuple must "
565 "be composed of integers in the range "
569 ((or (eq? v2
'n
) (eq? v2
'N
))
571 ;; NaN: digits form the diagnostic
572 (set self
'_int
(py-join "" (map str digits
)))
574 (set self
'_is_special
#t
)))
576 ;; finite number: digits give the coefficient
577 (set self
'_int
(py-join "" (map str digits
)))
579 (set self
'_is_special
#f
))
582 (+ "The third value in the tuple must "
583 "be an integer, or one of the "
584 "strings 'F', 'n', 'N'.")))))))))
586 ((isinstance value float
)
587 (let ((context (if (eq? context None
)
592 (+ "strict semantics for mixing floats and Decimals are "
595 (__init__ self
((ref Decimal
'from_float
) value
))))
599 (format #f
"Cannot convert ~a to Decimal" value
))))))
601 (define-inlinable (divmod x y
)
602 (values (quotient x y
) (modulo x y
)))
605 (syntax-rules (when let let
* if
)
607 ((_ (let () a ...
) . l
)
608 (begin a ...
(twix . l
)))
610 ((_ (let ((a aa
) ...
) b ...
) . l
)
611 (let ((a aa
) ...
) b ...
(twix . l
)))
612 ((_ (let (a ...
)) . l
)
614 ((_ (let* (a ...
) b ...
) . l
)
615 (let* (a ...
) b ...
(twix . l
)))
617 (begin (if . u
) (twix . l
)))
619 (begin (when . u
) (twix . l
)))
620 ((_ (a it code ...
) . l
)
621 (aif it a
(begin code ...
) (twix . l
)))))
623 (define-syntax-rule (norm-op self op
)
625 (set! op
(_convert_other op
))
626 (if (eq? op NotImplemented
)
630 (define-syntax-rule (get-context context code
)
631 (let ((context (if (eq? context None
)
636 (define-syntax-rule (un-special self context
)
637 (if (ref self
'_is_special
)
638 (let ((ans ((ref self
'_check_nans
) #:context context
)))
644 (define-syntax-rule (bin-special o1 o2 context
)
645 (if (or (ref o1
'_is_special
)
646 (ref o2
'_is_special
))
647 (or (un-special o1 context
) (un-special o2 context
))
650 (define-syntax-rule (add-special self other context
)
651 (or (bin-special self other context
)
652 (if (bool ((ref self
'_isinfinity
)))
653 ;; If both INF, same sign =>
654 ;; same as both, opposite => error.
655 (if (and (not (= (ref self
'_sign
) (ref other
'_sign
)))
656 (bool ((ref other
'_isinfinity
))))
657 ((cx-error context
) InvalidOperation
"-INF + INF")
659 (if (bool ((ref other
'_isinfinity
)))
660 (Decimal other
) ; Can't both be infinity here
663 (define-syntax-rule (mul-special self other context resultsign
)
664 (if (or (ref self
'_is_special
) (ref other
'_is_special
))
666 ((bin-special self other context
) it it
)
668 ((if (bool ((ref self
'_isinfinity
)))
669 (if (not (bool other
))
670 ((cx-error context
) InvalidOperation
"(+-)INF * 0")
671 (pylist-ref _SignedInfinity resultsign
))
674 (if (bool ((ref other
'_isinfinity
)))
675 (if (not (bool self
))
676 ((cx-error context
) InvalidOperation
"(+-)INF * 0")
677 (pylist-ref _SignedInfinity resultsign
))
681 (define-syntax-rule (div-special self other context sign
)
682 (if (or (ref self
'_is_special
) (ref other
'_is_special
))
684 ((bin-special self other context
) it it
)
686 ((and (bool ((ref self
'_isinfinity
))) (bool ((ref other
'_isinfinity
)))) it
687 ((cx-error context
) InvalidOperation
"(+-)INF/(+-)INF"))
689 ((bool ((ref self
'_isinfinity
))) it
690 (pylist-ref _SignedInfinity sign
))
692 ((bool ((ref other
'_isinfinity
))) it
693 ((cx-error context
) Clamped
"Division by infinity")
694 (_dec_from_triple sign
"0" (cx-etiny context
))))))
697 (define-python-class Decimal
(object)
698 "Floating point class for decimal arithmetic."
701 ;; Generally, the value of the Decimal instance is given by
702 ;; (-1)**_sign * _int * 10**_exp
703 ;; Special values are signified by _is_special == True
707 ((self sign coefficient exponent special
)
708 (set self
'_sign sign
)
709 (set self
'_int coefficient
)
710 (set self
'_exp exponent
)
711 (set self
'_is_special special
))
716 (_mk self __init__ a
))
718 (_mk self __init__ a b
))))
723 "Converts a float to a decimal number, exactly.
725 Note that Decimal.from_float(0.1) is not the same as Decimal('0.1').
726 Since 0.1 is not exactly representable in binary floating point, the
727 value is stored as the nearest representable value which is
728 0x1.999999999999ap-4. The exact equivalent of the value in decimal
729 is 0.1000000000000000055511151231257827021181583404541015625.
731 >>> Decimal.from_float(0.1)
732 Decimal('0.1000000000000000055511151231257827021181583404541015625')
733 >>> Decimal.from_float(float('nan'))
735 >>> Decimal.from_float(float('inf'))
737 >>> Decimal.from_float(-float('inf'))
739 >>> Decimal.from_float(-0.0)
744 (if (< x
0) (set! x
(- x
)))
746 (let lp
((l (string->list
(format #f
"~e" x
))) (r1 '()))
749 (let lp
((l l
) (r2 '()))
752 (let* ((n (length r2
))
753 (m (list->string
(append (reverse r1
) (reverse r2
))))
754 (e (+ (- n
) (string->number
(list->string l
)))))
757 (lp l
(cons x r2
))))))
760 (lp l
(cons x r1
))))))
763 ((isinstance f int
) ; handle integer inputs
765 ((not (isinstance f float
))
766 (raise (TypeError "argument must be int or float.")))
767 ((or (inf? f
) (nan? f
))
770 ((eq? f
(inf)) "Inf")
771 ((eq? f
(- (inf))) "-Inf"))))
773 (let* ((sign (if (>= f
0) 0 1))
777 (res (_dec_from_triple sign m e
)))
778 (if (eq? cls Decimal
)
784 "Returns whether the number is not actually one.
790 (if (ref self
'_is_special
)
791 (let ((exp (ref self
'_exp
)))
800 "Returns whether the number is infinite
802 0 if finite or not a number
806 (if (eq?
(ref self
'_exp
) 'F
)
807 (if (eq?
(ref self
'_sign
) 1)
813 (lam (self (= other None
) (= context None
))
814 "Returns whether the number is not actually one.
816 if self, other are sNaN, signal
817 if self, other are NaN return nan
820 Done before operations.
823 (let ((self_is_nan ((ref self
'_isnan
)))
827 ((ref other
'_isnan
)))))
829 (if (or self_is_nan other_is_nan
)
830 (let ((context (if (eq? context None
)
835 ((cx-error context
) InvalidOperation
"sNaN" self
))
836 ((eq? other_is_nan
2)
837 ((cx-error context
) InvalidOperation
"sNaN" other
))
839 ((ref self
'_fix_nan
) context
))
841 ((ref other
'_fix_nan
) context
))))
845 (define _compare_check_nans
846 (lambda (self other context
)
847 "Version of _check_nans used for the signaling comparisons
848 compare_signal, __le__, __lt__, __ge__, __gt__.
850 Signal InvalidOperation if either self or other is a (quiet
851 or signaling) NaN. Signaling NaNs take precedence over quiet
854 Return 0 if neither operand is a NaN.
857 (let ((context (if (eq? context None
)
861 (if (or (ref self
'_is_special
)
862 (ref other
'_is_special
))
864 (((ref self
'is_snan
))
867 "comparison involving sNaN" self
))
869 (((ref other
'is_snan
))
872 "comparison involving sNaN" other
))
874 (((ref self
'is_qnan
))
877 "comparison involving NaN" self
))
879 (((ref other
'is_qnan
))
882 "comparison involving NaN" other
))
889 "Return True if self is nonzero; otherwise return False.
891 NaNs and infinities are considered nonzero.
893 (or (ref self
'_is_special
) (not (equal?
(ref self
'_int
) "0")))))
897 "Compare the two non-NaN decimal instances self and other.
899 Returns -1 if self < other, 0 if self == other and 1
900 if self > other. This routine is for internal use only."
902 (let ((self_sign (ref self
'_sign
))
903 (other_sign (ref other
'_sign
)))
905 ((or (ref self
'_is_special
) (ref other
'_is_special
))
906 (let ((self_inf ((ref self
'_isinfinity
)))
907 (other_inf ((ref other
'_isinfinity
))))
909 ((eq? self_inf other_inf
) 0)
910 ((< self_inf other_inf
) -
1)
913 ;; check for zeros; Decimal('0') == Decimal('-0')
915 (if (not (bool other
))
917 (let ((s (ref other
'_sign
)))
922 (let ((s (ref self
'_sign
)))
927 ((< other_sign self_sign
)
929 ((< self_sign other_sign
)
933 (let ((self_adjusted ((ref self
'adjusted
)))
934 (other_adjusted ((ref other
'adjusted
)))
935 (self_exp (ref self
'_exp
))
936 (other_exp (ref other
'_exp
)))
938 ((= self_adjusted other_adjusted
)
939 (let ((self_padded (+ (ref self
'_int
)
940 (* "0" (- self_exp other_exp
))))
941 (other_padded (+ (ref other
'_int
)
942 (* "0" (- other_exp self_exp
)))))
944 ((equal? self_padded other_padded
)
946 ((< self_padded other_padded
)
954 ((> self_adjusted other_adjusted
)
963 ;; Note: The Decimal standard doesn't cover rich comparisons for
964 ;; Decimals. In particular, the specification is silent on the
965 ;; subject of what should happen for a comparison involving a NaN.
966 ;; We take the following approach:
968 ;; == comparisons involving a quiet NaN always return False
969 ;; != comparisons involving a quiet NaN always return True
970 ;; == or != comparisons involving a signaling NaN signal
971 ;; InvalidOperation, and return False or True as above if the
972 ;; InvalidOperation is not trapped.
973 ;; <, >, <= and >= comparisons involving a (quiet or signaling)
974 ;; NaN signal InvalidOperation, and return False if the
975 ;; InvalidOperation is not trapped.
977 ;; This behavior is designed to conform as closely as possible to
978 ;; that specified by IEEE 754.
981 (lam (self other
(= context None
))
982 (let* ((so (_convert_for_comparison self other
#:equality_op
#t
))
987 ((eq? other NotImplemented
)
989 ((bool ((ref self
'_check_nans
) other context
))
991 (else (= ((ref self
'_cmp
) other
) 0))))))
995 (lam (self other
(= context None
))
996 (let* ((so (_convert_for_comparison self other
#:equality_op
#t
))
1001 ((eq? other NotImplemented
)
1003 ((bool ((ref self
'_compare_check_nans
) other context
))
1005 (else (< ((ref self
'_cmp
) other
) 0)))))))
1007 (define __lt__
(lambda x
(apply (_xlt < ) x
)))
1008 (define __le__
(lambda x
(apply (_xlt <= ) x
)))
1009 (define __gt__
(lambda x
(apply (_xlt > ) x
)))
1010 (define __ge__
(lambda x
(apply (_xlt >= ) x
)))
1013 (lam (self other
(= context None
))
1014 "Compare self to other. Return a decimal value:
1016 a or b is a NaN ==> Decimal('NaN')
1017 a < b ==> Decimal('-1')
1018 a == b ==> Decimal('0')
1019 a > b ==> Decimal('1')
1021 (let ((other (_convert_other other
#:raiseit
#t
)))
1022 ;; Compare(NaN, NaN) = NaN
1023 (if (or (ref self
'_is_special
)
1025 (ref other
'_is_special
)))
1026 (aif it
((ref self
'_check_nans
) other context
)
1028 (Decimal ((ref self
'_cmp
) other
)))))))
1032 "x.__hash__() <==> hash(x)"
1034 ;; In order to make sure that the hash of a Decimal instance
1035 ;; agrees with the hash of a numerically equal integer, float
1036 ;; or Fraction, we follow the rules for numeric hashes outlined
1037 ;; in the documentation. (See library docs, 'Built-in Types').
1039 ((ref self
'_is_special
)
1041 (((ref self
'is_snan
))
1042 (raise (TypeError "Cannot hash a signaling NaN value.")))
1043 (((ref self
'is_snan
))
1044 (hash (nan) pyhash-N
))
1045 ((= 1 (ref self
'_sign
))
1046 (hash (- (inf)) pyhash-N
))
1048 (hash (inf) pyhash-N
))))
1051 (let* ((exp (ref self
'_exp
))
1054 (pow 10 exp pyhash-N
)
1055 (pow _PyHASH_10INV
(- exp
) pyhash-N
)))
1058 (modulo (* (int (ref self
'_int
)) exp_hash
)
1062 (if (>= self
0) hash_
(- hash_
))))
1063 (if (= ans -
1) -
2 ans
))))))
1067 "Represents the number as a triple tuple.
1069 To show the internals exactly as they are.
1071 (DecimalTuple (ref self
'_sign
)
1072 (tuple (map int
(ref self
'_int
)))
1075 (define as_integer_ratio
1077 "Express a finite Decimal instance in the form n / d.
1079 Returns a pair (n, d) of integers. When called on an infinity
1080 or NaN, raises OverflowError or ValueError respectively.
1082 >>> Decimal('3.14').as_integer_ratio()
1084 >>> Decimal('-123e5').as_integer_ratio()
1086 >>> Decimal('0.00').as_integer_ratio()
1089 (if (ref self
'_is_special
)
1090 (if ((ref self
'is_nan
))
1092 "cannot convert NaN to integer ratio"))
1093 (raise (OverflowError
1094 "cannot convert Infinity to integer ratio"))))
1096 (if (not (bool self
))
1098 (let* ((s (ref self
'_sign
))
1099 (n (int (ref self
'_int
)))
1100 (e (ref self
'_exp
))
1104 (/ 1 (expt 10 (- expt
)))))))
1105 (values (numerator x
)
1106 (denominator x
))))))
1110 "Represents the number as an instance of Decimal."
1111 ;# Invariant: eval(repr(d)) == d
1112 (format #f
"Decimal('~a')" (str self
))))
1115 (lam (self (= eng
#f
) (= context None
))
1116 "Return string representation of the number in scientific notation.
1118 Captures all of the information in the underlying representation.
1120 (let* ((sign (if (= (ref self
'_sign
) 0) "" "-"))
1121 (exp (ref self
'_exp
))
1122 (i (ref self
'_int
))
1123 (leftdigits (+ exp
(len i
)))
1129 ((ref self
'_is_special
)
1131 ((eq?
(ref self
'_exp
) 'F
)
1132 (+ sign
"Infinity"))
1133 ((eq?
(ref self
'_exp
) 'n
)
1134 (+ sign
"NaN" (ref self
'_int
)))
1135 (else ; self._exp == 'N'
1136 (+ sign
"sNaN" (ref self
'_int
)))))
1138 ;; dotplace is number of digits of self._int to the left of the
1139 ;; decimal point in the mantissa of the output string (that is,
1140 ;; after adjusting the exponent)
1142 ((and (<= exp
0) (> leftdigits -
6))
1143 ;; no exponent required
1144 (set! dotplace leftdigits
))
1147 ;; usual scientific notation: 1 digit on left of the point
1151 ;; engineering notation, zero
1152 (set! dotplace
(- (modulo (+ leftdigits
1) 3) 1)))
1154 ;; engineering notation, nonzero
1155 (set! dotplace
(- (modulo (+ leftdigits
1) 3) 1))))
1160 (set! fracpart
(+ "." (* "0" (- dotplace
)) i
)))
1161 ((>= dotplace
(len i
))
1162 (set! intpart
(+ i
(* "0" (- dotplace
(len i
)))))
1165 (set! intpart
(pylist-slice i None dotplace None
))
1166 (set! fracpart
(+ "." (pylist-slice i dotplace None None
)))))
1169 ((= leftdigits dotplace
)
1172 (let ((context (if (eq? context None
)
1176 (+ (pylist-ref '("e" "E") (cx-capitals context
))
1177 (format #f
"~@d" (- leftdigits dotplace
)))))))
1179 (+ sign intpart fracpart exppart
))))))
1181 (define to_eng_string
1182 (lam (self (= context None
))
1183 "Convert to a string, using engineering notation if an exponent is needed.
1184 Engineering notation has an exponent which is a multiple of 3. This
1185 can leave up to 3 digits to the left of the decimal place and may
1186 require the addition of either one or two trailing zeros.
1188 ((ref self
'__str__
) #:eng
#t
#:contect context
)))
1191 (lam (self (= context None
))
1192 "Returns a copy with the sign switched.
1194 Rounds, if it has reason.
1197 ((un-special self context
) it it
)
1198 (let* ((context (if (eq? context None
)
1201 (ans (if (and (not (bool self
))
1202 (not (eq?
(cx-rounding context
)
1204 ;; -Decimal('0') is Decimal('0'),
1205 ;; not Decimal('-0'), except
1206 ;; in ROUND_FLOOR rounding mode.
1207 ((ref self
'copy_abs
))
1208 ((ref self
'copy_negate
)))))
1210 ((ref ans
'_fix
) context
)))))
1213 (lam (self (= context None
))
1214 "Returns a copy, unless it is a sNaN.
1216 Rounds the number (if more than precision digits)
1219 ((un-special self context
) it it
)
1221 (let* ((context (if (eq? context None
)
1224 (ans (if (and (not (bool self
))
1225 (not (eq?
(cx-rounding context
)
1227 ;; -Decimal('0') is Decimal('0'),
1228 ;; not Decimal('-0'), except
1229 ;; in ROUND_FLOOR rounding mode.
1230 ((ref self
'copy_abs
))
1233 ((ref ans
'_fix
) context
)))))
1236 (lam (self (= round
#t
) (= context None
))
1237 "Returns the absolute value of self.
1239 If the keyword argument 'round' is false, do not round. The
1240 expression self.__abs__(round=False) is equivalent to
1244 ((not (bool round
)) it
1245 ((ref self
'copy_abs
)))
1247 ((un-special self context
) it it
)
1249 (if (= (ref self
'_sign
) 1)
1250 ((ref self
'__neg__
) #:context context
)
1251 ((ref self
'__pos__
) #:context context
)))))
1255 (lam (self other
(= context None
))
1256 "Returns self + other.
1258 -INF + INF (or the reverse) cause InvalidOperation errors.
1261 (let () (pk 1 1 other
))
1262 ((norm-op self other
) it it
)
1264 (let (get-context context
))
1266 ((add-special self other context
) it it
)
1270 (let* ((negativezero 0)
1271 (self_sign (ref self
'_sign
))
1272 (other_sign (ref other
'_sign
))
1273 (self_exp (ref self
'_exp
))
1274 (other_exp (ref other
'_exp
))
1275 (prec (cx-prec context
))
1276 (exp ((@ (guile) min
) self_exp other_exp
))
1280 (if (and (eq?
(cx-rounding context
) ROUND_FLOOR
)
1281 (not (= self_sign other_sign
)))
1282 ;; If the answer is 0, the sign should be negative,
1284 (set! negativezero
1)))
1286 ((if (and (not (bool self
)) (not (bool other
)))
1288 (set! sign
((@ (guile) min
) self_sign other_sign
))
1289 (if (= negativezero
1)
1291 (set! ans
(_dec_from_triple sign
"0" exp
))
1292 (set! ans
((ref ans
'_fix
) context
))
1296 ((if (not (bool self
))
1298 (set! exp
((@ (guile) max
) exp
(- other_exp prec
1)))
1299 (set! ans
((ref other
'_rescale
) exp
1300 (cx-rounding context
)))
1301 (set! ans
((ref ans
'_fix
) context
))
1305 ((if (not (bool other
))
1307 (set! exp
((@ (guile) max
) exp
(- self_exp prec
1)))
1308 (set! ans
((ref self
'_rescale
) exp
1309 (cx-rounding context
)))
1310 (set! ans
((ref ans
'_fix
) context
))
1316 (let* ((op1 (_WorkRep self
))
1317 (op2 (_WorkRep other
))
1318 (ab (_normalize op1 op2 prec
))
1321 (result (_WorkRep))))
1326 ((not (= (ref op1
'sign
) (ref op2
'sign
)))
1327 ;; Equal and opposite
1330 (set! ans
(_dec_from_triple negativezero
"0" exp
))
1331 (set! ans
((ref ans
'_fix
) context
))
1340 (if (= (ref op1
'sign
) 1)
1341 (let ((t (ref op1
'sign
)))
1342 (set result
'sign
1)
1343 (set op1
'sign
(ref op2
'sign
))
1345 (set result
'sign
0))
1347 ((= (ref op1
'sign
) 1)
1348 (set result
'sign
1)
1352 (set result
'sign
0)
1358 (if (= (ref op2
'sign
) 0)
1359 (set result
'int
(+ (ref op1
'int
) (ref op2
'int
)))
1360 (set result
'int
(- (ref op1
'int
) (ref op2
'int
))))
1362 (set result
'exp
(ref op1
'exp
))
1363 (set! ans
(Decimal result
))
1364 ((ref ans
'_fix
) context
)))))
1366 (define __radd__
(lambda x
(apply __add__ x
)))
1369 (lam (self other
(= context None
))
1370 "Return self - other"
1372 ((norm-op self other
) it it
)
1373 ((bin-special self other context
) it it
)
1374 ((ref self
'__add__
)
1375 ((ref other
'copy_negate
)) #:context context
))))
1378 (lam (self other
(= context None
))
1379 "Return other - self"
1381 ((norm-op self other
) it it
)
1382 ((ref 'other
'__sub__
) self
#:context context
))))
1385 (lam (self other
(= context None
))
1386 "Return self * other.
1388 (+-) INF * 0 (or its reverse) raise InvalidOperation.
1391 ((norm-op self other
) it it
)
1392 (let (get-context context
))
1394 (let ((resultsign (logxor (ref self
'_sign
)
1395 (ref other
'_sign
)))))
1397 ((mul-special self other context resultsign
) it it
)
1399 (let ((resultexp (+ (ref self
'_exp
) (ref other
'_exp
)))))
1401 ;; Special case for multiplying by zero
1402 ((or (not (bool self
)) (not (bool other
))) it
1403 (let ((ans (_dec_from_triple resultsign
"0" resultexp
)))
1404 ((ref ans
'_fix
) context
)))
1406 ;; Special case for multiplying by power of 10
1407 ((equal?
(ref self
'_int
) "1") it
1408 (let ((ans (_dec_from_triple resultsign
(ref other
'_int
) resultexp
)))
1409 ((ref ans
'_fix
) context
)))
1411 ((equal?
(ref other
'_int
) "1") it
1412 (let ((ans (_dec_from_triple resultsign
(ref self
'_int
) resultexp
)))
1413 ((ref ans
'_fix
) context
)))
1415 (let* ((op1 (_WorkRep self
))
1416 (op2 (_WorkRep other
))
1417 (ans (_dec_from_triple resultsign
1418 (str (* (ref op1
'int
) (ref op2
'int
)))
1420 ((ref ans
'_fix
) context
)))))
1422 (define __rmul__ __mul__
)
1425 (lam (self other
(= context None
))
1426 "Return self / other."
1428 ((norm-op self other
) it it
)
1429 (let (get-context context
))
1431 (let ((sign (logxor (ref self
'_sign
)
1432 (ref other
'_sign
)))))
1434 ((div-special self other context sign
) it it
)
1436 ;; Special cases for zeroes
1437 ((if (not (bool other
))
1438 (if (not (bool self
))
1439 ((cx-error context
) DivisionUndefined
"0 / 0")
1440 ((cx-error context
) DivisionByZero
"x / 0" sign
))
1445 (prec (cx-prec context
))
1446 (nself (len (ref self
'_int
)))
1447 (nother (len (ref other
'_int
))))
1448 (if (not (bool self
))
1450 (set! exp
(- (ref self
'_exp
) (ref other
'_exp
)))
1452 ;; OK, so neither = 0, INF or NaN
1453 (let ((shift (+ nother
(- nself
) prec
1))
1454 (op1 (_WorkRep self
))
1455 (op2 (_WorkRep other
)))
1456 (set! exp
(- (ref self
'_exp
) (ref other
'_exp
) shift
))
1460 (divmod (* (ref op1
'int
) (expt 10 shift
))
1462 (divmod (ref op1
'int
)
1463 (* (ref op2
'int
) (expt 10 shift
)))))
1464 (lambda (coeff- remainder
)
1466 (if (not (= remainder
0))
1467 ;; result is not exact adjust to ensure
1469 (if (= (modulo coeff-
5) 0)
1472 (let ((ideal_exp (- (ref self
'_exp
)
1473 (ref other
'_exp
))))
1474 (let lp
((coeff- coeff-
) (exp- exp
))
1475 (if (and (< exp- ideal_exp
)
1476 (= (modulo coeff
10) 0))
1477 (lp (/ coeff
10) (+ exp-
1))
1483 (let ((ans (_dec_from_triple sign
(str coeff
) exp
)))
1484 ((ref ans
'_fix
) context
))))))
1487 (lambda (self other context
)
1488 "Return (self // other, self % other), to context.prec precision.
1490 Assumes that neither self nor other is a NaN, that self is not
1491 infinite and that other is nonzero.
1496 (logxor (ref self
'_sign
)
1497 (ref other
'_sign
)))
1499 (if (bool ((ref other
'_isinfinity
)))
1501 ((@ (guile) min
) (ref self
'exp
) (ref other
'_exp
))))
1503 (- ((ref self
'adjusted
)) ((ref other
'adjusted
)))))))
1505 ((or (not (bool self
))
1506 (bool ((ref other
'_isinfinity
)))
1508 (list (_dec_from_triple sign
"0" 0)
1509 ((ref self
'_rescale
) ideal_exp
(cx-rounding context
))))
1511 ((if (<= expdiff
(cx-prec context
))
1512 (let ((op1 (_WorkRep self
))
1513 (op2 (_WorkRep other
)))
1514 (if (>= (ref op1
'exp
) (ref op2
'exp
))
1515 (set op1
'int
(* (ref op1
'int
)
1516 (expt 10 (- (ref op1
'exp
)
1518 (set op2
'int
(* (ref op2
'int
)
1519 (expt 10 (- (ref op2
'exp
)
1521 (call-with-values (lambda () (divmod (ref op1
'int
)
1524 (if (< q
(expt 10 (cx-prec context
)))
1525 (list (_dec_from_triple sign
(str q
) 0)
1526 (_dec_from_triple (ref self
'_sign
)
1532 ;; Here the quotient is too large to be representable
1533 (let ((ans ((cx-raise context
) DivisionImpossible
1534 "quotient too large in //, % or divmod")))
1535 (list ans ans
)))))))
1537 (define __rtruediv__
1538 (lam (self other
(= context None
))
1539 "Swaps self/other and returns __truediv__."
1541 ((norm-op self other
) it it
)
1542 ((ref other
'__truediv__
) self
#:context context
))))
1545 (lam (self other
(= context None
))
1547 Return (self // other, self % other)
1551 ((norm-op self other
) it it
)
1553 (let (get-context context
))
1555 ((add-special self other context
) it it
)
1557 (((ref self
'_check_nans
) other context
) it
1561 (logxor (ref self
'_sign
)
1562 (ref other
'_sign
))))))
1564 ((bool ((ref self
'_isinfinity
))) it
1565 (if (bool ((ref other
'_isinfinity
)))
1566 (let ((ans ((cx-error context
) InvalidOperation
1567 "divmod(INF, INF)")))
1569 (list (list-ref _SignedInfinity sign
)
1570 ((cx-raise context
) InvalidOperation
"INF % x"))))
1572 ((not (bool other
)) it
1573 (if (not (bool self
))
1574 (let ((ans ((cx-error context
) DivisionUndefined
1577 (list ((cx-error context
) DivisionByZero
"x // 0" sign
)
1578 ((cx-error context
) InvalidOperation
"x % 0"))))
1580 (call-with-values (lambda () ((ref self
'_divide
) other context
))
1581 (lambda (quotient remainder
)
1582 (let ((remainder ((ref remainder
'_fix
) context
)))
1583 (list quotient remainder
))))))))
1586 (lam (self other
(= context None
))
1587 "Swaps self/other and returns __divmod__."
1589 ((norm-op self other
) it it
)
1590 ((ref other
'__divmod__
) self
#:context context
))))
1593 (lam (self other
(= context None
))
1598 ((norm-op self other
) it it
)
1600 (let (get-context context
))
1602 ((bin-special self other context
) it it
)
1604 ((bool ((ref self
'_isinfinity
))) it
1605 ((cx-error context
) InvalidOperation
"INF % x"))
1607 ((not (bool other
)) it
1609 ((cx-error context
) InvalidOperation
"x % 0")
1610 ((cx-error context
) DivisionUndefined
"0 % 0")))
1612 (let* ((remainder ((ref self
'_divide
) other context
)))
1613 ((ref remainder
'_fix
) context
)))))
1616 (lam (self other
(= context None
))
1617 "Swaps self/other and returns __mod__."
1619 ((norm-op self other
) it it
)
1620 ((ref other
'__mod__
) self
#:context context
))))
1622 (define remainder_near
1623 (lam (self other
(= context None
))
1625 Remainder nearest to 0- abs(remainder-near) <= other/2
1628 ((norm-op self other
) it it
)
1630 (let (get-context context
))
1632 ((bin-special self other context
) it it
)
1634 ;; self == +/-infinity -> InvalidOperation
1635 ((bool ((ref self
'_isinfinity
))) it
1636 ((cx-error context
) InvalidOperation
"remainder_near(infinity, x)"))
1638 ;; other == 0 -> either InvalidOperation or DivisionUndefined
1639 ((not (bool other
)) it
1640 (if (not (bool self
))
1641 ((cx-error context
) InvalidOperation
"remainder_near(x, 0)")
1642 ((cx-error context
) DivisionUndefined
"remainder_near(0, 0)")))
1644 ;; other = +/-infinity -> remainder = self
1645 ((bool ((ref other
'_isinfinity
))) it
1646 (let ((ans (Decimal self
)))
1647 ((ref ans
'_fix
) context
)))
1649 ;; self = 0 -> remainder = self, with ideal exponent
1650 (let (let ((ideal_exponent ((@ (guile) min
) (ref self
'_exp
) (ref other
'_exp
))))))
1652 ((not (bool self
)) it
1653 (let ((ans (_dec_from_triple (ref self
'_sign
) "0" ideal_exponent
)))
1654 ((ref ans
'_fix
) context
)))
1656 ;; catch most cases of large or small quotient
1658 (- ((ref self
'adjusted
)) ((ref other
'adjusted
)))))))
1660 ((>= expdiff
(+ (cx-prec context
) 1)) it
1661 ;; expdiff >= prec+1 => abs(self/other) > 10**prec
1662 ((cx-error context
) DivisionImpossible
))
1665 ;; expdiff <= -2 => abs(self/other) < 0.1
1666 (let ((ans ((ref self
'_rescale
)
1667 ideal_exponent
(cx-rounding context
))))
1668 ((ref ans
'_fix
) context
)))
1670 (let ((op1 (_WorkRep self
))
1671 (op2 (_WorkRep other
)))
1673 ;; adjust both arguments to have the same exponent, then divide
1674 (if (>= (ref op1
'exp
) (ref op2
'exp
))
1675 (set op1
'int
(* (ref op1
'int
)
1676 (expt 10 (- (ref op1
'exp
) (ref op2
'exp
)))))
1677 (set op2
'int
(* (ref op2
'int
)
1678 (expt 10 (- (ref op2
'exp
) (ref op1
'exp
))))))
1680 (call-with-values (lambda () (divmod (ref op1
'int
) (ref op2
'int
)))
1683 ;; remainder is r*10**ideal_exponent; other is +/-op2.int *
1684 ;; 10**ideal_exponent. Apply correction to ensure that
1685 ;; abs(remainder) <= abs(other)/2
1686 (if (> (+ (* 2 r
) + (logand q
1)) (ref op2
'int
))
1687 (set! r
(- r
(ref op2
'int
)))
1690 (if (>= q
(expt 10 (cx-prec context
)))
1691 ((cx-error context
) DivisionImpossible
)
1692 (let ((sign (ref self
'_sign
)))
1694 (set! sign
(- 1 sign
))
1696 (let ((ans (_dec_from_triple sign
(str r
) ideal_exponent
)))
1697 ((ref ans
'_fix
) context
))))))))))
1699 (define __floordiv__
1700 (lam (self other
(= context None
))
1703 ((norm-op self other
) it it
)
1705 (let (get-context context
))
1707 ((bin-special self other context
) it it
)
1709 ((bool ((ref self
'_isinfinity
))) it
1710 (if (bool ((ref other
'_isinfinity
)))
1711 ((cx-error context
) InvalidOperation
"INF // INF")
1712 (pylist-ref _SignedInfinity
(logxor (ref self
'_sign
)
1713 (ref other
'_sign
)))))
1715 ((not (bool other
)) it
1717 ((cx-error context
) DivisionByZero
"x // 0"
1718 (logxor (ref self
'_sign
) (ref other
'_sign
)))
1719 ((cx-error context
) DivisionUndefined
"0 // 0")))
1721 ((ref self
'_divide
) other context
))))
1723 (define __rfloordiv__
1724 (lam (self other
(= context None
))
1725 "Swaps self/other and returns __floordiv__."
1727 ((norm-op self other
) it it
)
1728 ((ref other
'__floordiv__
) self
#:context context
))))
1732 "Float representation."
1733 (if ((ref self
'_isnan
))
1734 (if ((ref self
'is_snan
))
1735 (raise (ValueError "Cannot convert signaling NaN to float"))
1736 (if (= (ref self
'_sign
))
1739 (if ((ref self
'_isspecial
))
1740 (if (= (ref self
'_sign
))
1743 (float (str self
))))))
1747 "Converts self to an int, truncating if necessary."
1748 (if ((ref self
'_isnan
))
1749 (raise (ValueError "Cannot convert NaN to integer"))
1750 (if ((ref self
'_isspecial
))
1751 (raise (OverflowError "Cannot convert infinity to integer"))
1752 (let ((s (if (= (ref self
'_sign
) 1) -
1 1)))
1753 (if (>= (ref self
'_exp
) 0)
1754 (* s
(int (ref self
'_int
)) (expt 10 (ref self
'_exp
)))
1755 (* s
(int (or (bool (pylist-slice (ref self
'_int
)
1756 None
(ref self
'_exp
) None
))
1759 (define __trunc__ __int__
)
1762 (property (lambda (self) self
)))
1770 (lambda (self) self
))
1774 (complex (float self
))))
1777 (lambda (self context
)
1778 "Decapitate the payload of a NaN to fit the context"
1779 (let ((payload (ref self
'_int
))
1781 ;; maximum length of payload is precision if clamp=0,
1782 ;; precision-1 if clamp=1.
1784 (- (ref context
'prec
)
1785 (ref context
'clamp
))))
1787 (if (> (len payload
) max_payload_len
)
1788 (let ((payload (py-lstrip
1789 (pylist-slice payload
1790 (- (len payload
) max_payload_len
)
1792 (_dec_from_triple (ref self
'_sign
) payload
(ref self
'_exp
)
1797 (lambda (self context
)
1798 "Round if it is necessary to keep self within prec precision.
1800 Rounds and fixes the exponent. Does not raise on a sNaN.
1803 self - Decimal instance
1804 context - context used.
1808 (((ref self
'_is_special
)) it
1809 (if ((ref self
'_isnan
))
1810 ;; decapitate payload if necessary
1811 ((ref self
'_fix_nan
) context
)
1813 ;; self is +/-Infinity; return unaltered
1816 ;; if self is zero then exponent should be between Etiny and
1817 ;; Emax if clamp==0, and between Etiny and Etop if clamp==1.
1818 (let ((Etiny (cx-etiny context
))
1819 (Etop (cx-etop context
))))
1821 ((not (bool self
)) it
1822 (let* ((exp_max (if (= (cx-clamp context
) 0)
1825 (new_exp ((@ (guile) min
) ((@ (guile) max
) (ref self
'_exp
) Etiny
) exp_max
)))
1826 (if (not (= new_exp
(ref self
'_exp
)))
1828 ((cx-error context
) Clamped
)
1829 (_dec_from_triple (ref self
'_sign
) "0" new_exp
))
1832 ;; exp_min is the smallest allowable exponent of the result,
1833 ;; equal to max(self.adjusted()-context.prec+1, Etiny)
1834 (let ((exp_min (+ (len (ref self
'_int
))
1836 (- (cx-prec context
))))))
1837 ((> exp_min Etop
) it
1838 ;; overflow: exp_min > Etop iff self.adjusted() > Emax
1839 (let ((ans ((cx-error context
) Overflow
"above Emax"
1840 (ref self
'_sign
))))
1841 ((cx-error context
) Inexact
)
1842 ((cx-error context
) Rounded
)
1845 (let* ((self_is_subnormal (< exp_min Etiny
))
1846 (exp_min (if self_is_subnormal Etiny exp_min
))))
1848 ;; round if self has too many digits
1849 ((< (ref self
'_exp
) exp_min
) it
1850 (let ((digits (+ (len (ref self
'_int
))
1854 (set! self
(_dec_from_triple (ref self
'_sign
)
1859 (rounding_method (pylist-ref
1860 (ref self
'_pick_rounding_function
)
1861 (cx-rounding context
)))
1862 (changed (rounding_method self digits
))
1863 (coeff (or (bool (pylist-slice (ref self
'_int
)
1864 None digits None
)) "0")))
1867 (set! coeff
(str (+ (int coeff
) 1)))
1868 (if (> (len coeff
) (cx-prec context
))
1870 (set! coeff
(pylist-slice coeff None -
1 None
))
1871 (set! exp_min
(+ exp_min
1))))))
1873 ;; check whether the rounding pushed the exponent out of range
1874 (if (> exp_min Etop
)
1876 ((cx-error context
) Overflow
"above Emax"
1878 (set! ans
(_dec_from_triple (ref self
'_sign
) coeff exp_min
)))
1880 ;; raise the appropriate signals, taking care to respect
1881 ;; the precedence described in the specification
1882 (if (and changed self_is_subnormal
)
1883 ((cx-error context
) Underflow
))
1884 (if self_is_subnormal
1885 ((cx-error context
) Subnormal
))
1887 ((cx-error context
) Inexact
))
1889 ((cx-error context
) Rounded
)
1891 (if (not (bool ans
))
1892 ;; raise Clamped on underflow to 0
1893 ((cx-error context
) Clamped
))
1897 (if self_is_subnormal
1898 ((cx-error context
) Subnormal
))
1901 ;; fold down if clamp == 1 and self has too few digits
1902 (if (and (= (cx-clamp context
) 1) (> (ref self
'_exp
) Etop
))
1904 ((cx-error context
) Clamped
)
1905 (let ((self_padded (+ (ref self
'_int
)
1907 (- (ref self
'_exp
) Etop
)))))
1908 (_dec_from_triple (ref self
'_sign
) self_padded Etop
)))
1910 ;; here self was representable to begin with; return unchanged
1915 ;; for each of the rounding functions below:
1916 ;; self is a finite, nonzero Decimal
1917 ;; prec is an integer satisfying 0 <= prec < len(self._int)
1919 ;; each function returns either -1, 0, or 1, as follows:
1920 ;; 1 indicates that self should be rounded up (away from zero)
1921 ;; 0 indicates that self should be truncated, and that all the
1922 ;; digits to be truncated are zeros (so the value is unchanged)
1923 ;; -1 indicates that there are nonzero digits to be truncated
1927 "Also known as round-towards-0, truncate."
1928 (if (_all_zeros (ref self
'_int
) prec
)
1934 "Rounds away from 0."
1935 (- (_round_down self prec
))))
1937 (define _round_half_up
1939 "Rounds 5 up (away from 0)"
1941 ((in (pylist-ref (ref self
'_int
) prec
) "56789")
1943 ((_all_zeros (ref self
'_int
) prec
)
1947 (define _round_half_down
1950 (if (_exact_half (ref self
'_int
) prec
)
1952 (_round_half_up self prec
))))
1954 (define _round_half_even
1956 "Round 5 to even, rest to nearest."
1957 (if (and (_exact_half (ref self
'_int
) prec
)
1959 (in (pylist-ref (ref self
'_int
) (- prec
1)) "02468")))
1961 (_round_half_up self prec
)))
1963 (define _round_ceiling
1965 "Rounds up (not away from 0 if negative.)"
1966 (if (= (ref self
'_sign
) 1)
1967 (_round_down self prec
)
1968 (- (_round_down self prec
)))))
1970 (define _round_floor
1972 "Rounds down (not towards 0 if negative)"
1973 (if (= (ref self
'_sign
) 1)
1974 (- (_round_down self prec
))
1975 (_round_down self prec
))))
1979 "Round down unless digit prec-1 is 0 or 5."
1980 (if (and prec
(not (in (pylist-ref (ref self
'_int
) (- prec
1) "05"))))
1981 (_round_down self prec
)
1982 (- (_round_down self prec
)))))
1984 (define _pick_rounding_function
1985 (dict `((,ROUND_DOWN .
,_round_down
)
1986 (,ROUND_UP .
,_round_up
)
1987 (,ROUND_HALF_UP .
,_round_half_up
)
1988 (,ROUND_HALF_DOWN .
,_round_half_down
)
1989 (,ROUND_HALF_EVEN .
,_round_half_even
)
1990 (,ROUND_CEILING .
,_round_ceiling
)
1991 (,ROUND_FLOOR .
,_round_floor
)
1992 (,ROUND_05UP .
,_round_05up
))))
1995 (lam (self (= n None
))
1996 "Round self to the nearest integer, or to a given precision.
1998 If only one argument is supplied, round a finite Decimal
1999 instance self to the nearest integer. If self is infinite or
2000 a NaN then a Python exception is raised. If self is finite
2001 and lies exactly halfway between two integers then it is
2002 rounded to the integer with even last digit.
2004 >>> round(Decimal('123.456'))
2006 >>> round(Decimal('-456.789'))
2008 >>> round(Decimal('-3.0'))
2010 >>> round(Decimal('2.5'))
2012 >>> round(Decimal('3.5'))
2014 >>> round(Decimal('Inf'))
2015 Traceback (most recent call last):
2017 OverflowError: cannot round an infinity
2018 >>> round(Decimal('NaN'))
2019 Traceback (most recent call last):
2021 ValueError: cannot round a NaN
2023 If a second argument n is supplied, self is rounded to n
2024 decimal places using the rounding mode for the current
2027 For an integer n, round(self, -n) is exactly equivalent to
2028 self.quantize(Decimal('1En')).
2030 >>> round(Decimal('123.456'), 0)
2032 >>> round(Decimal('123.456'), 2)
2034 >>> round(Decimal('123.456'), -2)
2036 >>> round(Decimal('-Infinity'), 37)
2038 >>> round(Decimal('sNaN123'), 0)
2042 (if (not (eq? n None
))
2043 ;; two-argument form: use the equivalent quantize call
2044 (if (not (isinstance n int
))
2046 "Second argument to round should be integral"))
2047 (let ((exp (_dec_from_triple 0 "1" (- n
))))
2048 ((ref self
'quantize
) exp
)))
2050 ;; one-argument form§x
2051 (if (ref self
'_is_special
)
2052 (if ((ref self
'is_nan
))
2053 (raise (ValueError "cannot round a NaN"))
2054 (raise (OverflowError "cannot round an infinity")))
2055 (int ((ref self
'_rescale
) 0 ROUND_HALF_EVEN
))))))
2059 "Return the floor of self, as an integer.
2061 For a finite Decimal instance self, return the greatest
2062 integer n such that n <= self. If self is infinite or a NaN
2063 then a Python exception is raised.
2066 (if (ref self
'_is_special
)
2067 (if ((ref self
'is_nan
))
2068 (raise (ValueError "cannot round a NaN"))
2069 (raise (OverflowError "cannot round an infinity")))
2070 (int ((ref self
'_rescale
) 0 ROUND_FLOOR
)))))
2074 """Return the ceiling of self, as an integer.
2076 For a finite Decimal instance self, return the least integer n
2077 such that n >= self. If self is infinite or a NaN then a
2078 Python exception is raised.
2081 (if (ref self
'_is_special
)
2082 (if ((ref self
'is_nan
))
2083 (raise (ValueError "cannot round a NaN"))
2084 (raise (OverflowError "cannot round an infinity")))
2085 (int ((ref self
'_rescale
) 0 ROUND_CEILING
)))))
2088 (lam (self other third
(= context None
))
2089 "Fused multiply-add.
2091 Returns self*other+third with no rounding of the intermediate
2094 self and other are multiplied together, with no rounding of
2095 the result. The third operand is then added to the result,
2096 and a single final rounding is performed.
2099 (let ((other (_convert_other other
#:raiseit
#t
))
2100 (third (_convert_other third
#:raiseit
#t
))
2101 (fin (lambda (product)
2102 ((ref product
'__add__
) third context
)))))
2103 ;; compute product; raise InvalidOperation if either operand is
2104 ;; a signaling NaN or if the product is zero times infinity.
2105 ((if (or (ref self
'_is_special
) (ref other
'_is_special
))
2107 (let (get-context context
))
2108 ((equal?
(ref self
'_exp
) "N") it
2109 ((cx-error context
) InvalidOperation
"sNaN" self
))
2110 ((equal?
(ref other
'_exp
) "N") it
2111 ((cx-error context
) InvalidOperation
"sNaN" other
))
2112 ((equal?
(ref self
'_exp
) "n") it
2114 ((equal?
(ref other
'_exp
) "n") it
2116 ((equal?
(ref self
'_exp
) "F") it
2117 (if (not (bool other
))
2118 ((cx-error context
) InvalidOperation
"INF * 0 in fma")
2119 (pylist-ref _SignedInfinity
2120 (logxor (ref self
'_sign
)
2121 (ref other
'_sign
)))))
2122 ((equal?
(ref other
'_exp
) "F") it
2123 (if (not (bool self
))
2124 ((cx-error context
) InvalidOperation
"0 * INF in fma")
2125 (pylist-ref _SignedInfinity
2126 (logxor (ref self
'_sign
)
2127 (ref other
'_sign
)))))
2131 (_dec_from_triple (logxor (ref self
'_sign
) (ref other
'_sign
))
2132 (str (* (int (ref self
'_int
))
2133 (int (ref other
'_int
))))
2134 (+ (ref self
'_exp
) (ref other
'_exp
)))))))
2136 (define _power_modulo
2137 (lam (self other modulo
(= context None
))
2138 "Three argument version of __pow__"
2140 ((norm-op self other
) it it
)
2141 ((norm-op self modulo
) it it
)
2142 (let (get-context context
))
2144 ;; deal with NaNs: if there are any sNaNs then first one wins,
2145 ;; (i.e. behaviour for NaNs is identical to that of fma)
2146 (let ((self_is_nan (ref self
'_isnan
))
2147 (other_is_nan (ref other
'_isnan
))
2148 (modulo_is_nan (ref modulo
'_isnan
))))
2150 ((or (bool self_is_nan
) (bool other_is_nan
) (bool modulo_is_nan
)) it
2153 ((cx-error context
) InvalidOperation
"sNaN" self
))
2155 ((cx-error context
) InvalidOperation
"sNaN" other
))
2157 ((cx-error context
) InvalidOperation
"sNaN" modulo
))
2159 (_fix_nan self context
))
2160 ((bool other_is_nan
)
2161 (_fix_nan other context
))
2163 (_fix_nan modulo context
))))
2165 ;;check inputs: we apply same restrictions as Python's pow()
2166 ((not (and ((ref self
'_isinteger
))
2167 ((ref other
'_isinteger
))
2168 ((ref modulo
'_isinteger
)))) it
2169 ((cx-error context
) InvalidOperation
2170 (+ "pow() 3rd argument not allowed "
2171 "unless all arguments are integers")))
2174 ((cx-error context
) InvalidOperation
2175 (+ "pow() 2nd argument cannot be "
2176 "negative when 3rd argument specified")))
2178 ((not (bool modulo
)) it
2179 ((cx-error context
) InvalidOperation
2180 "pow() 3rd argument cannot be 0"))
2182 ;; additional restriction for decimal: the modulus must be less
2183 ;; than 10**prec in absolute value
2184 ((>= ((ref modulo
'adjusted
)) (cx-prec context
)) it
2185 ((cx-error context
) InvalidOperation
2186 (+ "insufficient precision: pow() 3rd "
2187 "argument must not have more than "
2188 "precision digits")))
2190 ;; define 0**0 == NaN, for consistency with two-argument pow
2191 ;; (even though it hurts!)
2192 ((and (not (bool other
)) (not (bool self
))) it
2193 ((cx-error context
) InvalidOperation
2194 (+ "at least one of pow() 1st argument "
2195 "and 2nd argument must be nonzero ;"
2196 "0**0 is not defined")))
2198 ;; compute sign of result
2199 (let ((sign (if ((ref other
'_iseven
))
2202 (base (_WorkRep ((ref self
'to_integral_value
))))
2203 (exponent (_WorkRep ((ref other
'to_integral_value
)))))
2206 ;; convert modulo to a Python integer, and self and other to
2207 ;; Decimal integers (i.e. force their exponents to be >= 0)
2208 (set! modulo
(abs (int modulo
)))
2210 ;; compute result using integer pow()
2211 (set! base
(guile:modulo
2212 (* (guile:modulo
(ref base
'int
) modulo
)
2213 (modulo-expt 10 (ref base
'exp
) modulo
))
2216 (let lp
((i (ref exponent
'exp
)))
2219 (set! base
(modulo-expt base
10 modulo
))
2222 (set! base
(modulo-expt base
(ref exponent
'int
) modulo
))
2224 (_dec_from_triple sign
(str base
) 0)))))
2226 (define _power_exact
2227 (lambda (self other p
)
2228 "Attempt to compute self**other exactly.
2230 Given Decimals self and other and an integer p, attempt to
2231 compute an exact result for the power self**other, with p
2232 digits of precision. Return None if self**other is not
2233 exactly representable in p digits.
2235 Assumes that elimination of special cases has already been
2236 performed: self and other must both be nonspecial; self must
2237 be positive and not numerically equal to 1; other must be
2238 nonzero. For efficiency, other._exp should not be too large,
2239 so that 10**abs(other._exp) is a feasible calculation."
2241 ;; In the comments below, we write x for the value of self and y for the
2242 ;; value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc
2243 ;; and yc positive integers not divisible by 10.
2245 ;; The main purpose of this method is to identify the *failure*
2246 ;; of x**y to be exactly representable with as little effort as
2247 ;; possible. So we look for cheap and easy tests that
2248 ;; eliminate the possibility of x**y being exact. Only if all
2249 ;; these tests are passed do we go on to actually compute x**y.
2251 ;; Here's the main idea. Express y as a rational number m/n, with m and
2252 ;; n relatively prime and n>0. Then for x**y to be exactly
2253 ;; representable (at *any* precision), xc must be the nth power of a
2254 ;; positive integer and xe must be divisible by n. If y is negative
2255 ;; then additionally xc must be a power of either 2 or 5, hence a power
2258 ;; There's a limit to how small |y| can be: if y=m/n as above
2261 ;; (1) if xc != 1 then for the result to be representable we
2262 ;; need xc**(1/n) >= 2, and hence also xc**|y| >= 2. So
2263 ;; if |y| <= 1/nbits(xc) then xc < 2**nbits(xc) <=
2264 ;; 2**(1/|y|), hence xc**|y| < 2 and the result is not
2267 ;; (2) if xe != 0, |xe|*(1/n) >= 1, so |xe|*|y| >= 1. Hence if
2268 ;; |y| < 1/|xe| then the result is not representable.
2270 ;; Note that since x is not equal to 1, at least one of (1) and
2271 ;; (2) must apply. Now |y| < 1/nbits(xc) iff |yc|*nbits(xc) <
2272 ;; 10**-ye iff len(str(|yc|*nbits(xc)) <= -ye.
2274 ;; There's also a limit to how large y can be, at least if it's
2275 ;; positive: the normalized result will have coefficient xc**y,
2276 ;; so if it's representable then xc**y < 10**p, and y <
2277 ;; p/log10(xc). Hence if y*log10(xc) >= p then the result is
2278 ;; not exactly representable.
2280 ;; if len(str(abs(yc*xe)) <= -ye then abs(yc*xe) < 10**-ye,
2281 ;; so |y| < 1/xe and the result is not representable.
2282 ;; Similarly, len(str(abs(yc)*xc_bits)) <= -ye implies |y|
2287 (define-syntax-rule (clean xc xe n
+)
2289 (if (= (modulo xc n
) 0)
2295 (let* ((x (_WorkRep self
))
2300 (let* ((y (_WorkRep other
))
2305 ;; case where xc == 1: result is 10**(xe*y), with xe*y
2306 ;; required to be an integer
2310 ;; result is now 10**(xe * 10**ye); xe * 10**ye must be integral
2315 (let ((exponent (* xe
(expt 10 ye
)))
2317 (if (= (ref y
'sign
) 1)
2318 (set! exponent
(- exponent
)))
2320 ;;if other is a nonnegative integer, use ideal exponent
2321 (if (and ((ref other
'_isinteger
)) (= (ref other
'_sign
) 0))
2323 (let ((ideal_exponent (* (ref self
'_exp
) (int other
))))
2324 (set! zeros
((@ (guile) min
) (- exponent ideal_exponent
) (- p
1)))))
2327 (_dec_from_triple 0 (+ "1" (* "0" zeros
)) (- exponent zeros
)))))
2329 ;; case where y is negative: xc must be either a power
2330 ;; of 2 or a power of 5.
2331 ((= (ref y
'sign
) 1) it
2332 (let ((last_digit (modulo xc
10)))
2336 ((= (modulo last_digit
2) 0)
2337 ;; quick test for power of 2
2339 ((not (= (logand xc
(- xc
)) xc
)) it
2341 ;; now xc is a power of 2; e is its exponent
2342 (let () (set! e
(- (_nbits xc
) 1)))
2346 ;; x = 2**e * 10**xe, e > 0, and y < 0.
2348 ;; The exact result is:
2350 ;; x**y = 5**(-e*y) * 10**(e*y + xe*y)
2352 ;; provided that both e*y and xe*y are integers.
2354 ;; 5**(-e*y) >= 10**p, then the result can't be expressed
2355 ;; exactly with p digits of precision.
2357 ;; Using the above, we can guard against large values of ye.
2358 ;; 93/65 is an upper bound for log(10)/log(5), so if
2360 ;; ye >= len(str(93*p//65))
2364 ;; -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5),
2366 ;; so 5**(-e*y) >= 10**p, and the coefficient of the result
2367 ;; can't be expressed in p digits.
2369 ;; emax >= largest e such that 5**e < 10**p.
2370 (let ((emax (quotient (* p
93) 65))))
2372 ((>= ye
(len (str emax
))) it
2375 ;; Find -e*y and -xe*y; both must be integers
2377 (set! e
(_decimal_lshift_exact (* e yc
) ye
))
2378 (set! xe
(_decimal_lshift_exact (* xe yc
) ye
)))
2380 ((or (eq? e None
) (eq? xe None
)) it
2387 (set! xc
(expt 5 e
))
2392 ;; e >= log_5(xc) if xc is a power of 5; we have
2393 ;; equality all the way up to xc=5**2658
2394 (let* ((e (quotient (* (_nbits xc
) 28) 65))
2397 (xc (quotient q xz
))
2398 (remainder (modulo q xz
))))
2400 ((not (= remainder
0)) it
2403 (let () (clean xc e
5 -
))
2405 ;; Guard against large values of ye, using the same logic as in
2406 ;; the 'xc is a power of 2' branch. 10/3 is an upper bound for
2408 (let ((emax (quotient (* p
10) 3))))
2410 ((>= ye
(len (str emax
))) it
2414 (set! e
(_decimal_lshift_exact (* e yc
) ye
))
2415 (set! xe
(_decimal_lshift_exact (* xe yc
) ye
)))
2417 ((or (eq? e None
) (eq? xe None
)) it
2424 (set! xc
(expt 2 e
))
2430 ((>= xc
(expt 10 p
)) it it
)
2433 (set! xe
(+ (- e
) (- xe
)))
2434 (_dec_from_triple 0 (str xc
) xe
)))))
2436 ;; now y is positive; find m and n such that y = m/n
2437 (let ((m #f
) (n #f
) (xc_bits (_nbits xc
))))
2440 (set! m
(* yc
(expt 10 ye
)))
2444 ((and (not (= xe
0)) (<= (len (str (abs (* yc xe
)))) (- ye
))) it
2447 ((and (not (= xc
1))
2448 (<= (len (str (* (abs yc
) xc_bits
))) (- ye
))) it
2453 (set! n
(expt 10 (- ye
)))
2456 (if (and (= (modulo m
2) 0) (= (modulo n
2) 0))
2458 (set! m
(quotient m
2))
2459 (set! n
(quotient n
2)))))
2461 (if (and (= (modulo m
5) 0) (= (modulo n
5) 0))
2463 (set! m
(quotient m
5))
2464 (set! n
(quotient n
5)))))
2467 ;; compute nth root of xc*10**xe
2471 ;; if 1 < xc < 2**n then xc isn't an nth power
2472 ((and (not (= xc
1)) (<= xc_bits n
)) it
2475 ((not (= (modulo xe n
) 0)) it
2479 (let ((a (ash 1 (- (quotient (- xc_bits
) n
)))))
2480 (set! xe
(quotient xe n
))
2482 ;; compute nth root of xc using Newton's method
2484 (let* ((x (expt a
(- n
1)))
2488 (if (not (and (= a q
) (= r
0)))
2494 (set! a
(quotient (+ (* a
(- n
1)) q
) n
))
2498 ;; now xc*10**xe is the nth root of the original xc*10**xe
2499 ;; compute mth power of xc*10**xe
2501 ;; if m > p*100//_log10_lb(xc) then m > p/log10(xc), hence xc**m >
2502 ;; 10**p and the result is not representable.
2503 ((and (> xc
1) (> m
(quotient (* p
100) (_log10_lb xc
)))) it
2507 (set! xc
(expt xc m
))
2510 ((> xc
(expt 10 p
)) it
2514 ;; by this point the result *is* exactly representable
2515 ;; adjust the exponent to get as close as possible to the ideal
2516 ;; exponent, if necessary
2517 (let* ((str_xc (str xc
))
2518 (zeros (if (and ((ref other
'_isinteger
))
2519 (= (ref other
'_sign
) 0))
2520 (let ((ideal_exponent
2521 (* (ref self
'_exp
) (int other
))))
2522 ((@ (guile) min
) (- xe ideal_exponent
)
2523 (- p
(len str_xc
))))
2525 (_dec_from_triple 0 (+ str_xc
(* '0' zeros
)) (- xe zeros
)))))))
2528 (lam (self other
(= modulo None
) (= context None
))
2529 "Return self ** other [ % modulo].
2531 With two arguments, compute self**other.
2533 With three arguments, compute (self**other) % modulo. For the
2534 three argument form, the following restrictions on the
2537 - all three arguments must be integral
2538 - other must be nonnegative
2539 - either self or other (or both) must be nonzero
2540 - modulo must be nonzero and must have at most p digits,
2541 where p is the context precision.
2543 If any of these restrictions is violated the InvalidOperation
2546 The result of pow(self, other, modulo) is identical to the
2547 result that would be obtained by computing (self**other) %
2548 modulo with unbounded precision but is computed more
2549 efficiently. It is always exact.
2553 ((not (eq? modulo None
)) it
2554 ((ref self
'_power_modulo
) other modulo context
))
2556 ((norm-op self other
) it it
)
2557 (let (get-context context
))
2559 ;; either argument is a NaN => result is NaN
2560 ((bin-special self other context
) it it
)
2562 ;; 0**0 = NaN (!), x**0 = 1 for nonzero x (including +/-Infinity)
2563 ((not (bool other
)) it
2564 (if (not (bool self
))
2565 ((cx-error context
) InvalidOperation
"0 ** 0")
2568 ;; result has sign 1 iff self._sign is 1 and other is an odd integer
2569 (let ((result_sign 0)))
2571 ((if (= (ref self
'_sign
) 1)
2573 ((if ((ref other
'_isinteger
))
2574 (if (not ((ref other
'_iseven
)))
2576 (set! result_sign
1)
2579 ;; -ve**noninteger = NaN
2580 ;; (-0)**noninteger = 0**noninteger
2582 ((cx-error context
) InvalidOperation
2583 "x ** y with x negative and y not an integer")
2586 ;; negate self, without doing any unwanted rounding
2587 (set! self
((ref self
'copy_negate
)))
2591 ;; 0**(+ve or Inf)= 0; 0**(-ve or -Inf) = Infinity
2592 ((not (bool self
)) it
2593 (if (= (ref other
'_sign
) 0)
2594 (_dec_from_triple result_sign
"0" 0)
2595 (pylist-ref _SignedInfinity result_sign
)))
2597 ;; Inf**(+ve or Inf) = Inf; Inf**(-ve or -Inf) = 0
2598 ((bool ((self '_isinfinity
))) it
2599 (if (= (ref other
'_sign
) 0)
2600 (pylist-ref _SignedInfinity result_sign
)
2601 (_dec_from_triple result_sign
"0" 0)))
2603 ;; 1**other = 1, but the choice of exponent and the flags
2604 ;; depend on the exponent of self, and on whether other is a
2605 ;; positive integer, a negative integer, or neither
2606 (let ((prec (cx-prec context
))))
2608 ((equal? self _One
) it
2610 (if ((ref other
'_isinteger
))
2611 ;; exp = max(self._exp*max(int(other), 0),
2612 ;; 1-context.prec) but evaluating int(other) directly
2613 ;; is dangerous until we know other is small (other
2614 ;; could be 1e999999999)
2617 ((= (ref other
'_sign
) 1)
2624 (set! exp
(* (ref self
'_exp
) multiplier
))
2625 (if (< exp
(- 1 prec
))
2627 (set! exp
(- 1 prec
))
2628 ((cx-error context
) Rounded
))))
2630 ((cx-error context
) Inexact
)
2631 ((cx-error context
) Rounded
)
2632 (set! exp
(- 1 prec
))))
2634 (_dec_from_triple result_sign
(+ "1" (* "0" (- exp
)) exp
))))
2636 ;; compute adjusted exponent of self
2637 (let ((self_adj ((ref self
'adjusted
)))))
2639 ;; self ** infinity is infinity if self > 1, 0 if self < 1
2640 ;; self ** -infinity is infinity if self < 1, 0 if self > 1
2641 ((bool ((ref other
'_isinfinity
))) it
2642 (if (eq?
(= (ref other
'_sign
) 0)
2644 (_dec_from_triple result_sign
"0" 0)
2645 (pylist-ref _SignedInfinity result_sign
)))
2647 ;; from here on, the result always goes through the call
2648 ;; to _fix at the end of this function.
2651 (bound (+ ((ref self
'_log10_exp_bound
))
2652 ((ref other
'adjusted
)))))
2654 ;; crude test to catch cases of extreme overflow/underflow. If
2655 ;; log10(self)*other >= 10**bound and bound >= len(str(Emax))
2656 ;; then 10**bound >= 10**len(str(Emax)) >= Emax+1 and hence
2657 ;; self**other >= 10**(Emax+1), so overflow occurs. The test
2658 ;; for underflow is similar.
2660 (if (eq?
(>= self_adj
0) (= (ref other
'_sign
) 0))
2661 ;; self > 1 and other +ve, or self < 1 and other -ve
2662 ;; possibility of overflow
2663 (if (>= bound
(len (str (cx-emax context
))))
2665 (_dec_from_triple result_sign
"1"
2666 (+ (cx-emax context
) 1))))
2668 ;; self > 1 and other -ve, or self < 1 and other +ve
2669 ;; possibility of underflow to 0
2670 (let ((Etiny (cx-etiny context
)))
2671 (if (>= bound
(len (str (- Etiny
))))
2672 (set! ans
(_dec_from_triple result_sign
"1" (- Etiny
1))))))
2674 ;; try for an exact result with precision +1
2675 (when (eq? ans None
)
2676 (set! ans
((ref self
'_power_exact
) other
(+ prec
1)))
2677 (when (not (eq? ans None
))
2678 (if (= result_sign
1)
2679 (set! ans
(_dec_from_triple 1 (ref ans
'_int
)
2683 ;; usual case: inexact result, x**y computed directly as exp(y*log(x))
2684 (when (eq? ans None
)
2691 (y (_WorkRep other
))
2695 (if (= (ref y
'sign
) 1)
2698 ;; compute correctly rounded result: start with precision +3,
2699 ;; then increase precision until result is unambiguously roundable
2704 (lambda () (_dpower xc xe yc ye
(+ p extra
)))
2707 (* 5 (expt 10 (- (len (str coeff
)) p
1))))
2709 (lp (+ extra
3)))))))
2711 (set! ans
(_dec_from_triple result_sign
(str coeff
) exp
))))))
2713 ;; unlike exp, ln and log10, the power function respects the
2714 ;; rounding mode; no need to switch to ROUND_HALF_EVEN here
2716 ;; There's a difficulty here when 'other' is not an integer and
2717 ;; the result is exact. In this case, the specification
2718 ;; requires that the Inexact flag be raised (in spite of
2719 ;; exactness), but since the result is exact _fix won't do this
2720 ;; for us. (Correspondingly, the Underflow signal should also
2721 ;; be raised for subnormal results.) We can't directly raise
2722 ;; these signals either before or after calling _fix, since
2723 ;; that would violate the precedence for signals. So we wrap
2724 ;; the ._fix call in a temporary context, and reraise
2726 (if (and exact
(not ((ref other
'_isinteger
))))
2728 ;; pad with zeros up to length context.prec+1 if necessary; this
2729 ;; ensures that the Rounded signal will be raised.
2730 (if (<= (len (ref ans
'_int
)) prec
)
2731 (let ((expdiff (+ prec
1 (- (len (ref ans
'_int
))))))
2732 (set! ans
(_dec_from_triple (ref ans
'_sign
)
2735 (- (ref ans
'_exp
) expdiff
)))))
2737 ;; create a copy of the current context, with cleared flags/traps
2738 (let ((newcontext (cx-copy context
)))
2739 (cx-clear_flags newcontext
)
2741 (for ((exception : _signals
)) ()
2742 (pylist-set! (cx-traps newcontext
) exception
0)
2745 ;; round in the new context
2746 (set! ans
((ref ans
'_fix
) newcontext
))
2748 ;; raise Inexact, and if necessary, Underflow
2749 ((cx-error newcontext
) Inexact
)
2750 (if (bool (pylist-ref (cx-flags newcontext
) Subnormal
))
2751 ((cx-error newcontext
) Underflow
))
2753 ;; propagate signals to the original context; _fix could
2754 ;; have raised any of Overflow, Underflow, Subnormal,
2755 ;; Inexact, Rounded, Clamped. Overflow needs the correct
2756 ;; arguments. Note that the order of the exceptions is
2758 (if (bool (pylist-ref (cx-flags newcontext
) Overflow
))
2759 ((cx-error newcontext
)
2760 Overflow
"above Emax" (ref ans
'_sign
)))
2762 (for ((exception : (list Underflow Subnormal
2763 Inexact Rounded Clamped
))) ()
2764 (if (bool (pylist-ref (cx-flags newcontext
) exception
))
2765 ((cx-error newcontext
) exception
)
2768 (set! ans
((ref ans
'_fix
) context
)))
2773 (lam (self other
(= context None
))
2774 "Swaps self/other and returns __pow__."
2776 ((norm-op self other
) it it
)
2777 ((ref 'other
'__pow__
) self
#:context context
))))
2780 (lam (self (= context None
))
2781 "Normalize- strip trailing 0s, change anything equal to 0 to 0e0"
2784 (let (get-context context
))
2785 ((un-special self context
) it it
)
2786 (let ((dup ((ref self _fix
) context
))))
2787 ((bool ((dup '_isinfinity
))) it dup
)
2788 ((not (bool dup
)) it
2789 (_dec_from_triple (ref dup
'_sign
) "0" 0))
2791 (let* ((_int (ref dup
'_int
))
2792 (exp_max (let ((i (cx-clamp context
)))
2795 (cx-etop context
)))))
2796 (let lp
((end (len _int
)) (exp (ref dup
'_exp
)))
2797 (if (and (equal?
(pylist-ref _int
(- end
1))
2800 (lp (- end
1) (+ exp
1))
2803 (pylist-slice _int None end None
)
2807 (lam (self exp
(= rounding None
) (= context None
))
2808 "Quantize self so its exponent is the same as that of exp.
2810 Similar to self._rescale(exp._exp) but with error checking.
2813 (let* ((exp (_convert_other exp
#:raiseit
#t
))
2814 (context (if (eq? context None
) (getcontext) context
))
2815 (rounding (if (eq? rounding None
)
2816 (cx-rounding context
)
2819 ((if (or ((self '_is_special
)) ((exp '_is_special
)))
2820 (let ((ans ((ref self
'_check_nans
) exp context
)))
2824 ((or (bool ((ref exp
'_isinfinity
))) (bool ((ref self
'_isinfinity
))))
2825 (if (and (bool ((ref exp
'_isinfinity
)))
2826 (bool ((ref self
'_isinfinity
))))
2827 (Decimal self
)) ; if both are inf, it is OK
2828 ((cx-error context
) InvalidOperation
"quantize with one INF"))
2833 ;; exp._exp should be between Etiny and Emax
2834 (let ((_eexp (ref exp
'_exp
))
2835 (Emax (cx-emax context
))))
2837 ((not (and (<= (cx-etiny context
) _eexp
) (<= _eexp Emax
))) it
2838 ((cx-error context
) InvalidOperation
2839 "target exponent out of bounds in quantize"))
2841 ((not (bool self
)) it
2842 (let ((ans (_dec_from_triple (ref self
'_sign
) "0" _eexp
)))
2843 ((ref ans
'_fix
) context
)))
2845 (let ((self_adjusted ((ref self
'adjusted
)))
2846 (prec (cx-prec context
))))
2848 ((> self_adjusted
(cx-emax context
)) it
2849 ((cx-error context
) InvalidOperation
2850 "exponent of quantize result too large for current context"))
2852 ((> (+ self_adjusted
(- _eexp
) 1) prec
) it
2853 ((cx-error context
) InvalidOperation
2854 "quantize result has too many digits for current context"))
2856 (let ((ans ((ref self
'_rescale
) _eexp rounding
))))
2858 (if (> ((ref ans
'adjusted
)) Emax
)
2859 ((cx-error context
) InvalidOperation
2860 "exponent of quantize result too large for current context"))
2862 (if (> (len (ref ans
'_int
)) prec
)
2863 ((cx-error context
) InvalidOperation
2864 "quantize result has too many digits for current context"))
2868 ;; raise appropriate flags
2869 (if (and (bool ans
) (< ((ref ans
'adjusted
)) (cx-emin context
)))
2870 ((cx-error context
) Subnormal
))
2872 (when (> (ref ans
'_exp
) (ref self
'_exp
))
2873 (if (not (equal? ans self
))
2874 ((cx-error context
) Inexact
))
2875 ((cx-error context
) Rounded
))
2877 ;; call to fix takes care of any necessary folddown, and
2878 ;; signals Clamped if necessary
2879 ((ref ans
'_fix
) context
)))))
2881 (define same_quantum
2882 (lam (self other
(= context None
))
2883 "Return True if self and other have the same exponent; otherwise
2886 If either operand is a special value, the following rules are used:
2887 * return True if both operands are infinities
2888 * return True if both operands are NaNs
2889 * otherwise, return False.
2891 (let ((other (_convert_other other
#:raiseit
#t
)))
2892 (if (or (ref self
'_is_special
) (ref other
'_is_special
))
2893 (or (and ((ref self
'is_nan
)) ((ref other
'is_nan
)))
2894 (and ((ref self
'is_infinite
)) ((ref other
'is_infinite
))))))
2896 (= (ref self
'_exp
) (ref other
'_exp
))))
2899 (lam (self exp rounding
)
2900 "Rescale self so that the exponent is exp, either by padding with zeros
2901 or by truncating digits, using the given rounding mode.
2903 Specials are returned without change. This operation is
2904 quiet: it raises no flags, and uses no information from the
2907 exp = exp to scale to (an integer)
2908 rounding = rounding mode
2912 ((ref self
'_is_special
) it
2915 ((not (bool self
)) it
2916 (_dec_from_triple (ref self
'_sign
) "0" exp
))
2918 (let ((_exp (ref self
'_exp
))
2919 (_sign (ref self
'_sign
))
2920 (_int (ref self
'_int
))))
2923 ;; pad answer with zeros if necessary
2924 (_dec_from_triple _sign
(+ _int
(* "0" (- _exp exp
))) exp
))
2927 ;; too many digits; round and lose data. If self.adjusted() <
2928 ;; exp-1, replace self by 10**(exp-1) before rounding
2929 (let ((digits (+ (len _int
) _exp
(- exp
))))
2931 (set! self
(_dec_from_triple _sign
"1" (- exp
1)))
2934 (let* ((this_function (pylist-ref (ref self
'_pick_rounding_function
)
2936 (changed (this_function self digits
))
2938 (pylist-slice _int None digits None
))
2941 (set! coeff
(str (+ (int coeff
) 1))))
2943 (_dec_from_triple _sign coeff exp
))))))
2946 (lam (self places rounding
)
2947 "Round a nonzero, nonspecial Decimal to a fixed number of
2948 significant figures, using the given rounding mode.
2950 Infinities, NaNs and zeros are returned unaltered.
2952 This operation is quiet: it raises no flags, and uses no
2953 information from the context.
2958 (raise (ValueError "argument should be at least 1 in _round")))
2959 ((or (ref self
'_is_special
) (not (bool self
)))
2962 (let ((ans ((ref self
'_rescale
) (+ ((self 'adjusted
)) 1 (- places
))
2964 ;; it can happen that the rescale alters the adjusted exponent;
2965 ;; for example when rounding 99.97 to 3 significant figures.
2966 ;; When this happens we end up with an extra 0 at the end of
2967 ;; the number; a second rescale fixes this.
2968 (if (not (= ((ref ans
'adjusted
)) ((ref self
'adjusted
))))
2969 (set! ans
((ref ans
'_rescale
) (+ ((ans 'adjusted
)) 1
2974 (define to_integral_exact
2975 (lam (self (= rounding None
) (= context None
))
2976 "Rounds to a nearby integer.
2978 If no rounding mode is specified, take the rounding mode from
2979 the context. This method raises the Rounded and Inexact flags
2982 See also: to_integral_value, which does exactly the same as
2983 this method except that it doesn't raise Inexact or Rounded.
2986 ((ref self
'_is_special
)
2987 (let ((ans ((ref self
'_check_nans
) #:context context
)))
2992 ((>= (ref self
'_exp
) 0)
2995 (_dec_from_triple (ref self
'_sign
) "0" 0))
2997 (let* ((context (if (eq? context None
) (getcontext) context
))
2998 (rounding (if (eq? rounding None
)
2999 (cx-rounding context
)
3001 (ans ((ref self
'_rescale
) 0 rounding
)))
3003 (if (not (equal? ans self
))
3004 ((cx-error context
) Inexact
))
3006 ((cx-error context
) Rounded
)
3010 (define to_integral_value
3011 (lam (self (= rounding None
) (= context None
))
3012 "Rounds to the nearest integer, without raising inexact, rounded."
3013 (let* ((context (if (eq? context None
) (getcontext) context
))
3014 (rounding (if (eq? rounding None
)
3015 (cx-rounding context
)
3019 ((ref self
'_is_special
)
3020 (let ((ans ((ref self
'_check_nans
) #:context context
)))
3025 ((>= (ref self
'_exp
) 0)
3029 ((ref self
'_rescale
) 0 rounding
))))))
3031 ;; the method name changed, but we provide also the old one,
3032 ;; for compatibility
3033 (define to_integral to_integral_value
)
3036 (lam (self (= context None
))
3037 "Return the square root of self."
3039 (let (get-context context
))
3041 ((if (ref self
'_is_special
)
3042 (let ((ans ((ref self
'_check_nans
) #:context context
)))
3045 (if (and (bool ((self '_isinfinity
))) (= (ref self
'_sign
) 0))
3051 ((not (bool self
)) it
3052 ;; exponent = self._exp // 2. sqrt(-0) = -0
3053 (let ((ans (_dec_from_triple (ref self
'_sign
) "0"
3054 (quotient (ref self
'_exp
) 2))))
3055 ((ref ans
'_fix
) context
)))
3057 ((= (ref self
'_sign
) 1) it
3058 ((cx-error context
) InvalidOperation
"sqrt(-x), x > 0"))
3060 ;; At this point self represents a positive number. Let p be
3061 ;; the desired precision and express self in the form c*100**e
3062 ;; with c a positive real number and e an integer, c and e
3063 ;; being chosen so that 100**(p-1) <= c < 100**p. Then the
3064 ;; (exact) square root of self is sqrt(c)*10**e, and 10**(p-1)
3065 ;; <= sqrt(c) < 10**p, so the closest representable Decimal at
3066 ;; precision p is n*10**e where n = round_half_even(sqrt(c)),
3067 ;; the closest integer to sqrt(c) with the even integer chosen
3068 ;; in the case of a tie.
3070 ;; To ensure correct rounding in all cases, we use the
3071 ;; following trick: we compute the square root to an extra
3072 ;; place (precision p+1 instead of precision p), rounding down.
3073 ;; Then, if the result is inexact and its last digit is 0 or 5,
3074 ;; we increase the last digit to 1 or 6 respectively; if it's
3075 ;; exact we leave the last digit alone. Now the final round to
3076 ;; p places (or fewer in the case of underflow) will round
3077 ;; correctly and raise the appropriate flags.
3079 ;; use an extra digit of precision
3080 (let* ((prec (+ (cx-prec context
) 1))
3081 (op (_WorkRep self
))
3082 (e (ash (ref op
'exp
) -
1))
3088 ;; write argument in the form c*100**e where e = self._exp//2
3089 ;; is the 'ideal' exponent, to be used if the square root is
3090 ;; exactly representable. l is the number of 'digits' of c in
3091 ;; base 100, so that 100**(l-1) <= c < 100**l.
3092 (if (= (logand (ref op
'exp
) 1) 1)
3094 (set! c
(* (ref op
'int
) 10))
3095 (set! l
(+ (ash (len (ref self
'_int
)) -
1) 1)))
3097 (set! c
(ref op
'int
))
3098 (set! l
(ash (+ (len (ref self
'_int
)) 1) -
1))))
3100 ;; rescale so that c has exactly prec base 100 'digits'
3101 (set! shift
(- prec l
))
3104 (set! c
(* c
(expt 100 shift
)))
3106 (let ((x (expt 100 (- shift
))))
3107 (set! c
(quotient c x
))
3108 (let ((remainder (modulo c x
)))
3109 (set! exact
(= remainder
0)))))
3111 (set! e
(- e shift
))
3113 ;; find n = floor(sqrt(c)) using Newton's method
3114 (let ((n (let lp
((n (expt 10 prec
)))
3115 (let ((q (quotient c n
)))
3118 (lp (ash (+ n q
) -
1)))))))
3120 (set! exact
(and exact
(= (* n n
) c
)))
3123 ;; result is exact; rescale to use ideal exponent e
3126 ;; assert n % 10**shift == 0
3127 (set! n
(quotient n
(expt 10 shift
)))
3128 (set! n
(* n
(expt 10 (- shift
)))))
3129 (set! e
(+ e shift
)))
3130 ;; result is not exact; fix last digit as described above
3131 (if (= (modulo n
5) 0)
3134 (let* ((ans (_dec_from_triple 0