annotate src/decimal/decimal.d @ 0:42cf4db6be32

Creation
author Paul (paul.d.anderson@comcast.net)
date Sat, 13 Mar 2010 13:22:25 -0800
parents
children a984d3056cc4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1 // TODO: ensure context flags are being set and cleared properly.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3 // TODO: add exp() add sqrt() add power():
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
4
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
5 // TODO: add a set/getPayload to Decimal
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
6
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
7 // TODO: unittest opPostDec && opPostInc.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
8
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
9 // TODO: this(str): add tests for just over/under int.max, int.min
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
10
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
11 // TODO: organize by structs, lib functions modules functions, etc.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
12
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
13 // TODO: opEquals unit test should include numerically equal testing.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
14
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
15 // TODO: write some test cases for flag setting. test the add/sub/mul/div functions
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
16
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
17 // TODO: to/from real or double (float) values needs definition and implementation.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
18
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
19 // TODO: need to determine the property name for dig and/or digits
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
20
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
21 module decimal.decimal;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
22
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
23 import decimal.context;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
24 import std.bigint;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
25 import std.conv;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
26 import std.ctype: isdigit;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
27 import std.math: PI, LOG2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
28 import std.stdio: write, writeln;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
29 import std.string;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
30
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
31 // special values
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
32 private enum SpVal {CLEAR, ZERO, INF, QNAN, SNAN};
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
33
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
34 // common decimal "numbers"
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
35 public:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
36 static immutable Decimal ONE = {spval:SpVal.CLEAR, ceff:{[1]}};
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
37 static immutable Decimal TEN = {spval:SpVal.CLEAR, ceff:{[10]}};
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
38 static immutable Decimal NaN = {spval:SpVal.QNAN};
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
39 static immutable Decimal POS_INF = {spval:SpVal.INF};
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
40 static immutable Decimal NEG_INF = {sign:true, SpVal.INF};
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
41 static immutable Decimal ZERO = {spval:SpVal.ZERO};
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
42 static immutable Decimal NEG_ZERO = {sign:true, SpVal.ZERO};
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
43
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
44 // active context
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
45 public DecimalContext context = DEFAULT_CONTEXT;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
46
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
47 // singleton ContextStack
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
48 private ContextStack contextStack;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
49
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
50 /// saves the current context
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
51 public void pushContext() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
52 contextStack.push();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
53 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
54
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
55 /// restores the previous context
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
56 public void popContext() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
57 contextStack.pop();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
58 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
59
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
60 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
61 * A struct representing an arbitrary-precision floating-point number.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
62 *
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
63 * The implementation follows the General Decimal Arithmetic
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
64 * Specification, Version 1.70 (25 Mar 2009),
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
65 * http://www.speleotrove.com/decimal. This specification conforms with
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
66 * IEEE standard 754-2008.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
67 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
68 struct Decimal {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
69
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
70 private:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
71 SpVal spval = SpVal.QNAN; // special values: default value is quiet NaN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
72 bool sign = false; // true if the value is negative, false otherwise.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
73 int expo = 0; // the exponent of the Decimal value
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
74 BigInt ceff; // the coefficient of the Decimal value
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
75 // NOTE: not a uint -- causes math problems down the line.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
76 int digits; // the number of decimal digits in this number.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
77 // (unless the number is a special value)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
78
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
79 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
80 // construction
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
81 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
82
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
83 public:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
84 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
85 * Constructs a Decimal number from a sign, a BigInt coefficient and
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
86 * an integer exponent.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
87 * The precision of the number is deduced from the number of decimal
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
88 * digits in the coefficient.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
89 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
90 this(const bool sign, const BigInt coefficient, const int exponent) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
91 this.clear();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
92 if (coefficient < BIG_ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
93 this.sign = !sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
94 this.ceff = -coefficient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
95 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
96 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
97 this.sign = sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
98 this.ceff = coefficient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
99 if (coefficient == BIG_ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
100 this.spval = SpVal.ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
101 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
102 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
103 this.expo = exponent;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
104 this.digits = numDigits(this.ceff, 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
105 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
106
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
107 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
108 * Constructs a Decimal number from a sign, an integer coefficient and
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
109 * an integer exponent.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
110 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
111 this(const bool sign, const int coefficient, const int exponent) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
112 this(sign, BigInt(coefficient), exponent);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
113 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
114
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
115 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
116 * Constructs a Decimal number from a sign, a special value string and
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
117 * an optional payload.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
118 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
119 this(const bool sign, string str, const uint payload = 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
120 this.clear();;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
121 this.sign = sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
122 if (icmp(str, "inf") == 0 || icmp(str, "infinity") == 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
123 spval = SpVal.INF;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
124 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
125 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
126 if (icmp(str, "snan") == 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
127 spval = SpVal.SNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
128 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
129 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
130 spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
131 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
132 ceff = payload;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
133 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
134
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
135 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
136 * Constructs a Decimal from a BigInt coefficient and an int exponent.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
137 * The sign of the number is the sign of the coefficient.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
138 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
139 this(const BigInt coefficient, const int exponent) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
140 this(false, coefficient, exponent);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
141 };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
142
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
143 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
144 * Constructs a Decimal from a BigInt.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
145 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
146 this(const BigInt coefficient) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
147 this(coefficient, 0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
148 };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
149
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
150 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
151 * Constructs a Decimal from an integer coefficient and an integer exponent.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
152 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
153 this(const long coefficient, const int exponent) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
154 this(BigInt(coefficient), exponent);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
155 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
156
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
157 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
158 * Constructs a Decimal from an integer value.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
159 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
160 this(const long coefficient) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
161 this(BigInt(coefficient), 0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
162 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
163
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
164 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
165 * Constructs a Decimal from an integer coefficient, exponent and precision.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
166 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
167 // TODO: should this set flags? probably not.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
168 this(const long coefficient, const int exponent, const int precision) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
169 this(coefficient, exponent);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
170 pushContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
171 context.precision = precision;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
172 setDigits(this);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
173 popContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
174 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
175
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
176 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
177 * Constructs a Decimal from a real value.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
178 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
179 this(const real r) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
180 string str = format("%.*G", cast(int)context.precision, r);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
181 this = str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
182 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
183
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
184 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
185 * Constructs a Decimal from a double value.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
186 * Set to the specified precision
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
187 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
188 this(const real r, int precision) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
189 string str = format("%.*E", precision, r);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
190 this = str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
191 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
192
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
193 // copy constructor
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
194 this(const Decimal that) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
195 this = that;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
196 };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
197
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
198 // construct from string representation
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
199 this(const string str) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
200 this = str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
201 };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
202
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
203 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
204 write("construction.");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
205 Decimal f = Decimal(BigInt(1234), 567);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
206 assert(f.toString() == "1.234E+570");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
207 f = Decimal(BigInt(1234));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
208 assert(f.toString() == "1234");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
209 f = Decimal(BigInt(123400));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
210 assert(f.toString() == "123400");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
211 f = Decimal(1234, 567);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
212 assert(f.toString() == "1.234E+570");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
213 f = Decimal(BigInt(1234));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
214 assert(f.toString() == "1234");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
215 f = Decimal(1234, 0, 9);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
216 assert(f.toString() == "1234.00000");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
217 Decimal dec = Decimal(1234, 1, 9);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
218 assert(dec.toString() == "12340.0000");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
219 dec = Decimal(12, 1, 9);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
220 assert(dec.toString() == "120.000000");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
221 dec = Decimal(int.max, -4, 9);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
222 assert(dec.toString() == "214748.365");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
223 dec = Decimal(int.max, -4);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
224 assert(dec.toString() == "214748.3647");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
225 dec = Decimal(1234567, -2, 5);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
226 assert(dec.toString() == "12346");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
227 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
228 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
229
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
230 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
231 write("this(str)....");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
232 Decimal f;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
233 string str = "0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
234 f = str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
235 assert(f.toString() == str);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
236 assert(f.toAbstract() == "[0,0,0]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
237 str = "0.00";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
238 f = str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
239 assert(f.toString() == str);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
240 assert(f.toAbstract() == "[0,0,-2]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
241 str = "0.0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
242 f = str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
243 assert(f.toString() == str);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
244 assert(f.toAbstract() == "[0,0,-1]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
245 f = "0.";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
246 assert(f.toString() == "0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
247 assert(f.toAbstract() == "[0,0,0]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
248 f = ".0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
249 assert(f.toString() == "0.0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
250 assert(f.toAbstract() == "[0,0,-1]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
251 str = "1.0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
252 f = str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
253 assert(f.toString() == str);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
254 assert(f.toAbstract() == "[0,10,-1]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
255 str = "1.";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
256 f = str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
257 assert(f.toString() == "1");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
258 assert(f.toAbstract() == "[0,1,0]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
259 str = ".1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
260 f = str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
261 assert(f.toString() == "0.1");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
262 assert(f.toAbstract() == "[0,1,-1]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
263 f = Decimal("123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
264 assert(f.toString() == "123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
265 f = Decimal("-123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
266 assert(f.toString() == "-123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
267 f = Decimal("1.23E3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
268 assert(f.toString() == "1.23E+3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
269 f = Decimal("1.23E");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
270 assert(f.toString() == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
271 f = Decimal("1.23E-");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
272 assert(f.toString() == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
273 f = Decimal("1.23E+");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
274 assert(f.toString() == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
275 f = Decimal("1.23E+3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
276 assert(f.toString() == "1.23E+3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
277 f = Decimal("1.23E3B");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
278 assert(f.toString() == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
279 f = Decimal("12.3E+007");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
280 assert(f.toString() == "1.23E+8");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
281 f = Decimal("12.3E+70000000000");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
282 assert(f.toString() == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
283 f = Decimal("12.3E+7000000000");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
284 assert(f.toString() == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
285 f = Decimal("12.3E+700000000");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
286 // writeln(f.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
287 assert(f.toString() == "1.23E+700000001");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
288 f = Decimal("12.3E-700000000");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
289 // writeln(f.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
290 assert(f.toString() == "1.23E-699999999");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
291 // NOTE: since there will still be adjustments -- maybe limit to 99999999?
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
292 f = Decimal("12.0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
293 assert(f.toString() == "12.0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
294 f = Decimal("12.3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
295 assert(f.toString() == "12.3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
296 f = Decimal("1.23E-3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
297 assert(f.toString() == "0.00123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
298 f = Decimal("0.00123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
299 assert(f.toString() == "0.00123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
300 f = Decimal("-1.23E-12");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
301 assert(f.toString() == "-1.23E-12");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
302 f = Decimal("-0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
303 assert(f.toString() == "-0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
304 f = Decimal("inf");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
305 assert(f.toString() == "Infinity");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
306 f = Decimal("NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
307 assert(f.toString() == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
308 f = Decimal("-NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
309 assert(f.toString() == "-NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
310 f = Decimal("sNaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
311 assert(f.toString() == "sNaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
312 f = Decimal("Fred");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
313 assert(f.toString() == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
314 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
315 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
316
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
317 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
318 * dup property
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
319 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
320 const Decimal dup() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
321 Decimal cp;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
322 cp.sign = sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
323 cp.spval = spval;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
324 cp.ceff = ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
325 cp.expo = expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
326 return cp;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
327 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
328
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
329 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
330 // assignment
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
331 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
332
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
333 /// Assigns a Decimal (makes a copy)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
334 void opAssign(const Decimal that) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
335 this.sign = that.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
336 this.spval = that.spval;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
337 this.digits = that.digits;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
338 this.expo = that.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
339 this.ceff = that.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
340 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
341
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
342 /// Assigns a floating point value.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
343 void opAssign(const real r) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
344 this = Decimal(r);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
345 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
346
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
347 /// Assign an integer value
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
348 void opAssign(const long n) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
349 spval = (n == 0) ? SpVal.ZERO : SpVal.CLEAR;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
350 sign = n < 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
351 ceff = sign ? -n : n;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
352 expo = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
353 digits = numDigits(ceff, 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
354 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
355
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
356 /// Assign a BigInt
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
357 void opAssign(const BigInt big) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
358 spval = (big == BIG_ZERO) ? SpVal.ZERO : SpVal.CLEAR;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
359 sign = big < 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
360 ceff = sign ? -big : big;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
361 expo = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
362 digits = numDigits(ceff, 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
363 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
364
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
365 /// Assigns a string
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
366 void opAssign(const string numeric_string) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
367 clear();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
368 sign = false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
369
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
370 // strip, copy, tolower
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
371 char[] str = strip(numeric_string).dup;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
372 tolowerInPlace(str);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
373
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
374 // get sign, if any
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
375 if (startsWith(str,"-")) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
376 sign = true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
377 str = str[1..$];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
378 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
379 else if (startsWith(str,"+")) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
380 str = str[1..$];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
381 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
382
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
383 // check for NaN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
384 if (startsWith(str,"nan")) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
385 spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
386 if (str == "nan") {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
387 ceff = BIG_ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
388 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
389 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
390 // set payload
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
391 str = str[3..$];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
392 // ensure string is all digits
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
393 foreach(char c; str) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
394 if (!isdigit(c)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
395 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
396 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
397 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
398 // convert string to payload
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
399 ceff = BigInt(str.idup);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
400 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
401 };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
402
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
403 // check for sNaN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
404 if (startsWith(str,"snan")) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
405 spval = SpVal.SNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
406 if (str == "snan") {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
407 ceff = BIG_ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
408 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
409 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
410 // set payload
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
411 str = str[4..$];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
412 // ensure string is all digits
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
413 foreach(char c; str) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
414 if (!isdigit(c)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
415 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
416 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
417 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
418 // convert string to payload
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
419 ceff = BigInt(str.idup);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
420 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
421 };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
422
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
423 // check for infinity
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
424 if (str == "inf" || str == "infinity") {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
425 spval = SpVal.INF;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
426 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
427 };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
428
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
429 clear();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
430 // check for exponent
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
431 int pos = find(str, 'e');
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
432 if (pos > 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
433 // if it's just a trailing 'e', return NaN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
434 if (pos == str.length - 1) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
435 spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
436 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
437 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
438 // split the string into coefficient and exponent
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
439 char[] xstr = str[pos+1..$];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
440 str = str[0..pos];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
441 // assume exponent is positive
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
442 bool xneg = false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
443 // check for minus sign
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
444 if (startsWith(xstr, "-")) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
445 xneg = true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
446 xstr = xstr[1..$];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
447 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
448 // check for plus sign
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
449 else if (startsWith(xstr, "+")) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
450 xstr = xstr[1..$];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
451 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
452
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
453 // ensure it's not now empty
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
454 if (xstr.length < 1) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
455 spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
456 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
457 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
458
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
459 // ensure exponent is all digits
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
460 foreach(char c; xstr) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
461 if (!isdigit(c)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
462 spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
463 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
464 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
465 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
466
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
467 // trim leading zeros
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
468 while (xstr[0] == '0' && xstr.length > 1) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
469 xstr = xstr[1..$];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
470 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
471
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
472 // make sure it will fit into an int
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
473 if (xstr.length > 10) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
474 spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
475 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
476 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
477 if (xstr.length == 10) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
478 // try to convert it to a long (should work) and
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
479 // then see if the long value is too big (or small)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
480 long lex = to!long(xstr);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
481 if ((xneg && (-lex < int.min)) || lex > int.max) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
482 spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
483 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
484 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
485 expo = cast(int) lex;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
486 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
487 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
488 // everything should be copacetic at this point
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
489 expo = to!int(xstr);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
490 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
491 if (xneg) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
492 expo = -expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
493 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
494 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
495 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
496 expo = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
497 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
498
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
499 // remove trailing decimal point
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
500 if (endsWith(str, ".")) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
501 str = str[0..$-1];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
502 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
503 // strip leading zeros
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
504 while (str[0] == '0' && str.length > 1) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
505 str = str[1..$];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
506 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
507
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
508 // remove internal decimal point
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
509 int point = find(str, '.');
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
510 if (point >= 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
511 // excise the point and adjust exponent
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
512 str = str[0..point] ~ str[point+1..$];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
513 int diff = str.length - point;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
514 expo -= diff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
515 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
516
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
517 // ensure string is not empty
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
518 if (str.length < 1) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
519 spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
520 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
521 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
522
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
523 // ensure string is all digits
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
524 foreach(char c; str) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
525 if (!isdigit(c)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
526 spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
527 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
528 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
529 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
530 // convert string to BigInt
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
531 ceff = BigInt(str.idup);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
532 digits = numDigits(ceff, str.length);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
533 if (ceff == BIG_ZERO) spval = SpVal.ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
534
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
535 }; // end opAssign(string)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
536
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
537 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
538 // string representations
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
539 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
540
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
541 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
542 * Converts a Decimal to an abstract string representation.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
543 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
544 private const string toAbstract() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
545 switch (spval) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
546 case SpVal.SNAN:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
547 string payload = ceff == BIG_ZERO ? "" : "," ~ ceff.toString();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
548 return format("[%d,%s%s]", sign ? 1 : 0, "sNaN", payload);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
549 case SpVal.QNAN:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
550 string payload = ceff == BIG_ZERO ? "" : "," ~ ceff.toString();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
551 return format("[%d,%s%s]", sign ? 1 : 0, "qNaN", payload);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
552 case SpVal.INF:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
553 return format("[%d,%s]", sign ? 1 : 0, "inf");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
554 default:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
555 return format("[%d,%s,%d]", sign ? 1 : 0, ceff.toString(), expo);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
556 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
557 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
558
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
559 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
560 * Converts a Decimal to a string representation.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
561 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
562 const string toString() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
563
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
564 // string representation of special values
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
565 if (spval > SpVal.ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
566 string str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
567 switch(spval) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
568 case SpVal.ZERO:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
569 str = "0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
570 break;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
571 case SpVal.INF:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
572 str = "Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
573 break;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
574 case SpVal.SNAN:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
575 str = "sNaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
576 break;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
577 default:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
578 str = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
579 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
580 if (spval >= SpVal.QNAN && ceff != BIG_ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
581 str ~= ceff.toString();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
582 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
583 return sign ? "-" ~ str : str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
584 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
585
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
586 // string representation of finite numbers
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
587 string cstr = ceff.toString();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
588 int clen = cstr.length;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
589 int adjx = expo + clen - 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
590
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
591 // if exponent is small, don't use exponential notation
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
592 if (expo <= 0 && adjx >= -6) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
593 // if exponent is not zero, insert a decimal point
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
594 if (expo != 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
595 int point = std.math.abs(expo);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
596 // if coefficient is too small, pad with zeroes
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
597 if (point > clen) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
598 cstr = zfill(cstr, point);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
599 clen = cstr.length;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
600 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
601 // if no chars precede the decimal point, prefix a zero
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
602 if (point == clen) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
603 cstr = "0." ~ cstr;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
604 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
605 // otherwise insert a decimal point
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
606 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
607 cstr = insert(cstr, cstr.length - point, ".");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
608 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
609 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
610 return sign ? "-" ~ cstr : cstr;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
611 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
612 // use exponential notation
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
613 // else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
614 if (clen > 1) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
615 cstr = insert(cstr, 1, ".");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
616 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
617 string xstr = to!string(adjx);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
618 if (adjx >= 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
619 xstr = "+" ~ xstr;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
620 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
621 string str = cstr ~ "E" ~ xstr;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
622 if (sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
623 return "-" ~ str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
624 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
625 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
626 return str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
627 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
628 // } // end else
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
629
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
630 }; // end toString()
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
631
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
632 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
633 * Converts a Decimal to an engineering string representation.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
634 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
635 const string toEngString() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
636 return toString();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
637 };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
638
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
639 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
640 * Converts a Decimal to a scientific string representation.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
641 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
642 const string toSciString() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
643 return toString();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
644 };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
645
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
646 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
647 write("to-sci-str...");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
648 Decimal dec = Decimal(false, 123, 0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
649 assert(dec.toString() == "123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
650 assert(dec.toAbstract() == "[0,123,0]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
651 dec = Decimal(true, 123, 0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
652 assert(dec.toString() == "-123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
653 assert(dec.toAbstract() == "[1,123,0]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
654 dec = Decimal(false, 123, 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
655 assert(dec.toString() == "1.23E+3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
656 assert(dec.toAbstract() == "[0,123,1]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
657 dec = Decimal(false, 123, 3);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
658 assert(dec.toString() == "1.23E+5");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
659 assert(dec.toAbstract() == "[0,123,3]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
660 dec = Decimal(false, 123, -1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
661 assert(dec.toString() == "12.3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
662 assert(dec.toAbstract() == "[0,123,-1]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
663 dec = Decimal(false, 123, -5);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
664 assert(dec.toString() == "0.00123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
665 assert(dec.toAbstract() == "[0,123,-5]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
666 dec = Decimal(false, 123, -10);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
667 assert(dec.toString() == "1.23E-8");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
668 assert(dec.toAbstract() == "[0,123,-10]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
669 dec = Decimal(true, 123, -12);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
670 assert(dec.toString() == "-1.23E-10");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
671 assert(dec.toAbstract() == "[1,123,-12]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
672 dec = Decimal(false, 0, 0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
673 assert(dec.toString() == "0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
674 assert(dec.toAbstract() == "[0,0,0]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
675 dec = Decimal(false, 0, -2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
676 assert(dec.toString() == "0.00");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
677 assert(dec.toAbstract() == "[0,0,-2]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
678 dec = Decimal(false, 0, 2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
679 assert(dec.toString() == "0E+2");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
680 assert(dec.toAbstract() == "[0,0,2]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
681 dec = Decimal(true, 0, 0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
682 assert(dec.toString() == "-0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
683 assert(dec.toAbstract() == "[1,0,0]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
684 dec = Decimal(false, 5, -6);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
685 assert(dec.toString() == "0.000005");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
686 assert(dec.toAbstract() == "[0,5,-6]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
687 dec = Decimal(false, 50,-7);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
688 assert(dec.toString() == "0.0000050");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
689 assert(dec.toAbstract() == "[0,50,-7]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
690 dec = Decimal(false, 5, -7);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
691 assert(dec.toString() == "5E-7");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
692 assert(dec.toAbstract() == "[0,5,-7]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
693 dec = Decimal(false, "inf");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
694 assert(dec.toString() == "Infinity");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
695 assert(dec.toAbstract() == "[0,inf]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
696 dec = Decimal(true, "inf");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
697 assert(dec.toString() == "-Infinity");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
698 assert(dec.toAbstract() == "[1,inf]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
699 dec = Decimal(false, "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
700 assert(dec.toString() == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
701 assert(dec.toAbstract() == "[0,qNaN]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
702 dec = Decimal(false, "NaN", 123);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
703 assert(dec.toString() == "NaN123");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
704 assert(dec.toAbstract() == "[0,qNaN,123]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
705 dec = Decimal(true, "sNaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
706 assert(dec.toString() == "-sNaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
707 assert(dec.toAbstract() == "[1,sNaN]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
708 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
709 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
710
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
711
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
712 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
713 // member properties
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
714 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
715
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
716 /// returns the exponent of this Decimal
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
717 const int exponent() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
718 return this.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
719 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
720 /// returns the coefficient of this Decimal
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
721 const BigInt coefficient() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
722 return this.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
723 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
724
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
725 /// returns the sign of this Decimal
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
726 const int sgn() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
727 if (isZero) return 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
728 return sign ? -1 : 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
729 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
730
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
731 /// returns a Decimal with the same exponent as this Decimal
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
732 /// and a coefficient of 1.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
733 const Decimal quantum() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
734 return Decimal(1, this.expo);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
735 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
736
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
737 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
738 // floating point properties
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
739 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
740
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
741 static int precision() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
742 return context.precision;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
743 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
744
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
745 /// returns the default value for this type (NaN)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
746 static Decimal init() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
747 return NaN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
748 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
749
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
750 /// Returns NaN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
751 static Decimal nan() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
752 return NaN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
753 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
754
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
755 /// Returns positive infinity.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
756 static Decimal infinity() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
757 return POS_INF;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
758 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
759
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
760 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
761 // classification properties
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
762 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
763
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
764 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
765 * Returns true if this number is canonical representation (always true).
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
766 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
767 const bool isCanonical() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
768 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
769 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
770
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
771 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
772 * Returns true if this Decimal is +/- zero.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
773 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
774 const bool isZero() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
775 return spval == SpVal.ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
776 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
777
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
778 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
779 * Returns true if this Decimal is a quiet or signaling NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
780 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
781 const bool isNaN() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
782 return this.spval == SpVal.QNAN || this.spval == SpVal.SNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
783 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
784
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
785 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
786 * Returns true if this Decimal is a signaling NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
787 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
788 const bool isSignaling() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
789 return this.spval == SpVal.SNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
790 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
791
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
792 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
793 * Returns true if this Decimal is a quiet NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
794 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
795 const bool isQuiet() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
796 return this.spval == SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
797 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
798
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
799 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
800 * Returns true if this Decimal is +/- infinity.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
801 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
802 const bool isInfinite() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
803 return this.spval == SpVal.INF;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
804 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
805
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
806 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
807 * Returns true if this Decimal is not +/- infinity and not a NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
808 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
809 const bool isFinite() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
810 return spval != SpVal.INF
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
811 && spval != SpVal.QNAN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
812 && spval != SpVal.SNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
813 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
814
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
815 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
816 * Returns true if this Decimal is a NaN or infinity.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
817 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
818 const bool isSpecial() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
819 return spval == SpVal.INF
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
820 || spval == SpVal.QNAN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
821 || spval == SpVal.SNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
822 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
823
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
824 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
825 * Returns true if this Decimal is negative. (Includes -0)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
826 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
827 const bool isSigned() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
828 return this.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
829 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
830
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
831 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
832 * Returns true if this Decimal is subnormal.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
833 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
834 const bool isSubnormal() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
835 if (spval != SpVal.CLEAR) return false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
836 return adjustedExponent < context.eMin;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
837 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
838
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
839 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
840 * Returns true if this Decimal is subnormal.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
841 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
842 const bool isNormal() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
843 if (spval != SpVal.CLEAR) return false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
844 return adjustedExponent >= context.eMin;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
845 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
846
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
847 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
848 // comparison
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
849 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
850
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
851 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
852 * Returns -1, 0 or 1, if this number is less than, equal to or
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
853 * greater than the argument, respectively.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
854 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
855 int opCmp(const Decimal that) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
856 return icompare(this, that);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
857 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
858
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
859 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
860 * Returns true if this Decimal is equal to the specified Decimal.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
861 * A NaN is not equal to any number, not even to another NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
862 * Infinities are equal if they have the same sign.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
863 * Zeros are equal regardless of sign.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
864 * Finite numbers are equal if they are numerically equal to the current precision.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
865 * A Decimal may not be equal to itself (this != this) if it is a NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
866 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
867 const bool opEquals(ref const Decimal that) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
868 // if either is NaN...
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
869 if (this.isNaN || that.isNaN) return false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
870
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
871 // if either is infinite...
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
872 if (this.isInfinite || that.isInfinite) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
873 return (this.spval == that.spval && this.sign == that.sign);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
874 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
875
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
876 // if either is zero...
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
877 if (this.isZero || that.isZero) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
878 return (this.isZero && that.isZero);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
879 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
880 // if their signs differ
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
881 if (this.sign != that.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
882 return false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
883 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
884
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
885 // if they have the same representation, they are equal
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
886 if (this.expo == that.expo && this.ceff == that.ceff) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
887 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
888 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
889
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
890 // otherwise they are equal if they represent the same value
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
891 // NOTE: this is only a check to current precision.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
892 Decimal result = this - that;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
893 return result.isZero;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
894 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
895
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
896 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
897 write("equals.......");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
898 Decimal op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
899 Decimal op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
900 op1 = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
901 op2 = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
902 assert(op1 != op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
903 op1 = "inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
904 op2 = "inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
905 assert(op1 == op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
906 op2 = "-inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
907 assert(op1 != op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
908 op1 = "-inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
909 assert(op1 == op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
910 op2 = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
911 assert(op1 != op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
912 op1 = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
913 assert(op1 != op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
914 op2 = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
915 assert(op1 == op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
916 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
917 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
918
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
919 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
920 // unary arithmetic operators
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
921 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
922
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
923 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
924 * unary minus -- returns a copy with the opposite sign.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
925 * This operation may set flags -- equivalent to
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
926 * subtract('0', b);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
927 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
928 const Decimal opNeg() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
929 return minus(this);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
930 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
931
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
932 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
933 * unary plus -- returns a copy.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
934 * This operation may set flags -- equivalent to
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
935 * add('0', a);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
936 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
937 const Decimal opPos() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
938 return plus(this);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
939 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
940
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
941 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
942 * Returns this + 1.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
943 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
944 Decimal opPostInc() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
945 this += ONE;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
946 return this;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
947 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
948
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
949 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
950 * Returns this - 1.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
951 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
952 Decimal opPostDec() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
953 this -= ONE;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
954 return this;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
955 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
956
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
957 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
958 // binary arithmetic operators
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
959 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
960
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
961 /// Adds a Decimal to this and returns the Decimal result
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
962 const Decimal opAdd(T:Decimal)(const T addend) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
963 return add(this, addend);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
964 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
965
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
966 // Adds a number to this and returns the result.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
967 const Decimal opAdd(T)(const T addend) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
968 return add(this, Decimal(addend), context);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
969 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
970
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
971 const Decimal opSub(T:Decimal)(const T subtrahend) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
972 return subtract(this, subtrahend);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
973 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
974
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
975 const Decimal opSub(T)(const T subtrahend) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
976 return subtract(this, Decimal(subtrahend), context);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
977 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
978
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
979 const Decimal opMul(T:Decimal)(const T factor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
980 return multiply(this, factor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
981 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
982
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
983 const Decimal opMul(T)(const T factor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
984 return multiply(this, Decimal(factor));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
985 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
986
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
987 const Decimal opDiv(T:Decimal)(const T divisor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
988 return divide(this, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
989 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
990
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
991 const Decimal opDiv(T)(const T divisor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
992 return divide(this, Decimal(divisor));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
993 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
994
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
995 const Decimal opMod(T:Decimal)(const T divisor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
996 return remainder(this, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
997 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
998
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
999 const Decimal opMod(T)(const T divisor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1000 return remainder(this, Decimal(divisor));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1001 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1002
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1003 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1004 // arithmetic assignment operators
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1005 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1006
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1007 Decimal opAddAssign(T)(const T addend) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1008 this = this + addend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1009 return this;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1010 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1011
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1012 Decimal opSubAssign(T)(const T subtrahend) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1013 this = this - subtrahend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1014 return this;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1015 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1016
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1017 Decimal opMulAssign(T)(const T factor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1018 this = this * factor;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1019 return this;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1020 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1021
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1022 Decimal opDivAssign(T)(const T divisor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1023 this = this / divisor;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1024 return this;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1025 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1026
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1027 Decimal opModAssign(T)(const T divisor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1028 this = this % divisor;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1029 return this;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1030 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1031
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1032 //-----------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1033 // nextUp, nextDown, nextAfter
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1034 //-----------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1035
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1036 const Decimal nextUp() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1037 return nextPlus(this);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1038 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1039
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1040 const Decimal nextDown() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1041 return nextMinus(this);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1042 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1043
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1044 const Decimal nextAfter(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1045 return nextToward(this, dcm);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1046 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1047
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1048 private:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1049 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1050 * clears the special value flags
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1051 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1052 void clear() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1053 spval = SpVal.CLEAR;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1054 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1055
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1056 const int adjustedExponent() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1057 return expo + digits - 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1058 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1059
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1060 const bool overflow() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1061 return adjustedExponent > context.eMax;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1062 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1063
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1064 unittest{
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1065 write("overflow.....");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1066 Decimal dec = Decimal(123, 99);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1067 assert(dec.overflow);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1068 dec = Decimal(12, 99);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1069 assert(dec.overflow);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1070 dec = Decimal(1, 99);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1071 assert(!dec.overflow);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1072 dec = Decimal(9, 99);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1073 assert(!dec.overflow);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1074 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1075 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1076
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1077 } // end struct Decimal
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1078
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1079
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1080 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1081 // context functions
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1082 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1083
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1084 // TODO: this is actually a property of the context.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1085
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1086 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1087 * Returns radix of this representation (10).
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1088 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1089 public int radix() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1090 return 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1091 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1092
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1093 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1094 write("radix........");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1095 assert(radix() == 10);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1096 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1097 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1098
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1099 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1100 // classification functions
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1101 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1102
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1103 public string classify(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1104 if (dcm.isSignaling()) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1105 return "sNaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1106 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1107 if (dcm.isQuiet) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1108 return "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1109 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1110 if (dcm.isInfinite) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1111 return dcm.sign ? "-Infinity" : "+Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1112 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1113 if (dcm.isSubnormal) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1114 return dcm.sign ? "-Subnormal" : "+Subnormal";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1115 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1116 if (dcm.isZero) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1117 return dcm.sign ? "-Zero" : "+Zero";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1118 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1119 return dcm.sign ? "-Normal" : "+Normal";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1120 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1121
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1122 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1123 * Returns true if this number is canonical representation (always true).
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1124 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1125 public bool isCanonical(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1126 return dcm.isCanonical;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1127 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1128
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1129 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1130 * Returns true if this Decimal is a signaling NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1131 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1132 public bool isSignaling(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1133 return dcm.isSignaling;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1134 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1135
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1136 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1137 * Returns true if the specified Decimal is a quiet NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1138 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1139 public bool isQuiet(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1140 return dcm.isQuiet;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1141 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1142
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1143 public bool isFinite(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1144 return dcm.isFinite;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1145 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1146
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1147 public bool isInfinite(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1148 return dcm.isInfinite;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1149 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1150
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1151 public bool isNaN(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1152 return dcm.isNaN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1153 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1154
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1155 public bool isNormal(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1156 return dcm.isNormal;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1157 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1158
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1159 public bool isSubnormal(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1160 return dcm.isSubnormal;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1161 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1162
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1163 public bool isZero(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1164 return dcm.isZero;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1165 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1166
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1167 public bool isSigned(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1168 return dcm.isSigned;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1169 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1170
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1171 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1172 write("classify.....");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1173 Decimal dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1174 dcm = "Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1175 assert(classify(dcm) == "+Infinity");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1176 dcm = "1E-10";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1177 assert(classify(dcm) == "+Normal");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1178 dcm = "2.50";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1179 assert(classify(dcm) == "+Normal");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1180 dcm = "0.1E-99";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1181 assert(classify(dcm) == "+Subnormal");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1182 dcm = "0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1183 assert(classify(dcm) == "+Zero");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1184 dcm = "-0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1185 assert(classify(dcm) == "-Zero");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1186 dcm = "-0.1E-99";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1187 assert(classify(dcm) == "-Subnormal");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1188 dcm = "-1E-10";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1189 assert(classify(dcm) == "-Normal");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1190 dcm = "-2.50";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1191 assert(classify(dcm) == "-Normal");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1192 dcm = "-Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1193 assert(classify(dcm) == "-Infinity");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1194 dcm = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1195 assert(classify(dcm) == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1196 dcm = "-NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1197 assert(classify(dcm) == "NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1198 dcm = "sNaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1199 assert(classify(dcm) == "sNaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1200
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1201 dcm = Decimal("2.50");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1202 assert(isCanonical(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1203
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1204 dcm = Decimal("2.50");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1205 assert(isFinite(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1206 dcm = Decimal("-0.3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1207 assert(isFinite(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1208 dcm = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1209 assert(isFinite(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1210 dcm = Decimal("Inf");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1211 assert(!isFinite(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1212 dcm = Decimal("-Inf");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1213 assert(!isFinite(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1214 dcm = Decimal("NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1215 assert(!isFinite(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1216
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1217 dcm = Decimal("2.50");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1218 assert(!isInfinite(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1219 dcm = Decimal("-Inf");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1220 assert(isInfinite(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1221 dcm = Decimal("NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1222 assert(!isInfinite(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1223
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1224 dcm = Decimal("2.50");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1225 assert(!isNaN(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1226 dcm = Decimal("NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1227 assert(isNaN(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1228 dcm = Decimal("-sNaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1229 assert(isNaN(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1230
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1231 dcm = Decimal("2.50");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1232 assert(isNormal(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1233 dcm = Decimal("0.1E-99");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1234 assert(!isNormal(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1235 dcm = Decimal("0.00");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1236 assert(!isNormal(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1237 dcm = Decimal("-Inf");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1238 assert(!isNormal(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1239 dcm = Decimal("NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1240 assert(!isNormal(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1241 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1242
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1243 dcm = Decimal("2.50");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1244 assert(!isQuiet(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1245 dcm = Decimal("NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1246 assert(isQuiet(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1247 dcm = Decimal("sNaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1248 assert(!isQuiet(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1249
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1250 dcm = Decimal("2.50");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1251 assert(!isSignaling(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1252 dcm = Decimal("NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1253 assert(!isSignaling(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1254 dcm = Decimal("sNaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1255 assert(isSignaling(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1256
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1257 dcm = Decimal("2.50");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1258 assert(!isSigned(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1259 dcm = Decimal("-12");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1260 assert(isSigned(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1261 dcm = Decimal("-0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1262 assert(isSigned(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1263
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1264 dcm = Decimal("2.50");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1265 assert(!isSubnormal(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1266 dcm = Decimal("0.1E-99");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1267 assert(isSubnormal(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1268 dcm = Decimal("0.00");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1269 assert(!isSubnormal(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1270 dcm = Decimal("-Inf");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1271 assert(!isSubnormal(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1272 dcm = Decimal("NaN");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1273 assert(!isSubnormal(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1274
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1275 dcm = Decimal("0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1276 assert(isZero(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1277 dcm = Decimal("2.50");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1278 assert(!isZero(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1279 dcm = Decimal("-0E+2");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1280 assert(isZero(dcm));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1281
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1282 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1283
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1284 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1285 // copy functions
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1286 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1287
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1288 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1289 * Returns a copy of the operand.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1290 * The copy is unaffected by context; no flags are changed.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1291 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1292 Decimal copy(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1293 Decimal cpy = dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1294 return cpy;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1295 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1296
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1297 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1298 * Returns a copy of the operand with a positive sign.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1299 * The copy is unaffected by context; no flags are changed.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1300 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1301 Decimal copyAbs(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1302 Decimal cpy = dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1303 cpy.sign = false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1304 return cpy;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1305 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1306
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1307 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1308 * Returns a copy of the operand with the sign inverted.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1309 * The copy is unaffected by context; no flags are changed.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1310 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1311 Decimal copyNegate(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1312 Decimal cpy = dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1313 cpy.sign = !dcm.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1314 return cpy;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1315 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1316
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1317 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1318 * Returns a copy of the first operand with the sign of the second operand.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1319 * The copy is unaffected by context; no flags are changed.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1320 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1321 Decimal copySign(const Decimal dcm1, const Decimal dcm2) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1322 Decimal cpy = dcm1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1323 cpy.sign = dcm2.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1324 return cpy;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1325 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1326
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1327 // TODO: these should actually be compare-total assertions
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1328 // This is probably true of other unit tests as well
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1329 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1330 write("copy.........");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1331 Decimal dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1332 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1333 dcm = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1334 expd = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1335 assert(copy(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1336 dcm = "-1.00";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1337 expd = "-1.00";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1338 assert(copy(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1339 dcm = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1340 expd = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1341
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1342 assert(copyAbs(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1343 dcm = "-1.00";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1344 expd = "1.00";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1345 assert(copyAbs(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1346 dcm = "101.5";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1347 expd = "-101.5";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1348
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1349 assert(copyNegate(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1350 Decimal dcm1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1351 Decimal dcm2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1352 dcm1 = "1.50";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1353 dcm2 = "7.33";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1354 expd = "1.50";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1355
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1356 assert(copySign(dcm1, dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1357 dcm1 = "-1.50";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1358 dcm2 = "7.33";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1359 expd = "1.50";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1360 assert(copySign(dcm1, dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1361 dcm1 = "1.50";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1362 dcm2 = "-7.33";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1363 expd = "-1.50";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1364 assert(copySign(dcm1, dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1365 dcm1 = "-1.50";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1366 dcm2 = "-7.33";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1367 expd = "-1.50";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1368 assert(copySign(dcm1, dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1369 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1370 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1371
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1372 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1373 // plus, minus and abs functions
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1374 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1375
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1376 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1377 * unary minus -- returns a copy with the opposite sign.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1378 * This operation may set flags -- equivalent to
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1379 * subtract('0', b);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1380 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1381 Decimal minus(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1382 Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1383 if(isInvalidOperation(dcm, result)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1384 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1385 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1386 result = copyNegate(dcm);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1387 round(result);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1388 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1389 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1390
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1391 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1392 * unary plus -- returns a copy.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1393 * This operation may set flags -- equivalent to
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1394 * add('0', a);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1395 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1396 Decimal plus(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1397 Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1398 if(isInvalidOperation(dcm, result)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1399 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1400 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1401 result = dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1402 round(result);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1403 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1404 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1405
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1406 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1407 write("minus/plus...");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1408 // NOTE: result should equal 0+this or 0-this
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1409 Decimal zero = Decimal(0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1410 Decimal dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1411 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1412 dcm = "1.3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1413 expd = zero + dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1414 assert(+dcm == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1415 dcm = "-1.3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1416 expd = zero + dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1417 assert(+dcm == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1418 dcm = "1.3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1419 expd = zero - dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1420 assert(-dcm == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1421 dcm = "-1.3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1422 expd = zero - dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1423 assert(-dcm == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1424 // TODO: add tests that check flags.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1425 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1426 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1427
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1428 /// Returns a new Decimal equal to the absolute value of this Decimal.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1429 public Decimal abs(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1430 Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1431 if(isInvalidOperation(dcm, result)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1432 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1433 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1434 result = copyAbs(dcm);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1435 round(result);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1436 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1437 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1438
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1439 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1440 // TODO: add rounding tests
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1441 write("abs..........");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1442 Decimal dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1443 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1444 dcm = "sNaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1445 assert(abs(dcm).isQuiet);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1446 assert(context.flags && INVALID_OPERATION);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1447 dcm = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1448 assert(abs(dcm).isQuiet);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1449 assert(context.flags && INVALID_OPERATION);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1450 dcm = "Inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1451 expd = "Inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1452 assert(abs(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1453 dcm = "-Inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1454 expd = "Inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1455 assert(abs(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1456 dcm = "0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1457 expd = "0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1458 assert(abs(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1459 dcm = "-0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1460 expd = "0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1461 assert(abs(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1462 dcm = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1463 expd = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1464 assert(abs(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1465 dcm = -100;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1466 expd = 100;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1467 assert(abs(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1468 dcm = 101.5;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1469 expd = 101.5;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1470 assert(abs(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1471 dcm = -101.5;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1472 assert(abs(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1473 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1474 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1475
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1476 public Decimal nextPlus(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1477 Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1478 if (isInvalidOperation(dcm, result)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1479 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1480 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1481 if (dcm.isInfinite && dcm.sign) return -context.max();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1482 int adjx = dcm.expo + dcm.digits - context.precision;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1483 if (adjx < context.eTiny) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1484 return Decimal(true, 0, context.eTiny);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1485 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1486 Decimal addend = Decimal(1, adjx);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1487 result = dcm + addend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1488 if (result > context.max) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1489 result = POS_INF;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1490 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1491 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1492 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1493
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1494 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1495 write("next-plus....");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1496 pushContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1497 context.eMax = 999;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1498 context.eMin = -999;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1499 Decimal dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1500 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1501 dcm = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1502 expd = "1.00000001";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1503 assert(nextPlus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1504 dcm = 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1505 expd = "10.0000001";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1506 assert(nextPlus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1507 dcm = 1E5;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1508 expd = "100000.001";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1509 assert(nextPlus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1510 dcm = 1E8;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1511 expd = "100000001";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1512 assert(nextPlus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1513 // num digits exceeds precision...
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1514 dcm = "1234567891";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1515 expd = "1.23456790E9";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1516 assert(nextPlus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1517 // result < tiny
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1518 dcm = "-1E-1007";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1519 expd = "-0E-1007";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1520 assert(nextPlus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1521 dcm = "-1.00000003";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1522 expd = "-1.00000002";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1523 assert(nextPlus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1524 dcm = "-Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1525 expd = "-9.99999999E+999";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1526 assert(nextPlus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1527 popContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1528 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1529 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1530
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1531 public Decimal nextMinus(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1532 Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1533 if (isInvalidOperation(dcm, result)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1534 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1535 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1536 if (dcm.isInfinite && !dcm.sign) return context.max();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1537 // This is necessary to catch the special case where ceff == 1
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1538 Decimal red = reduce(dcm);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1539 int adjx = red.expo + red.digits - context.precision;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1540 if (dcm.ceff == 1) adjx--;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1541 if (adjx < context.eTiny) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1542 return Decimal(false, 0, context.eTiny);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1543 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1544 Decimal addend = Decimal(1, adjx);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1545 result = dcm - addend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1546 if (result < -context.max) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1547 result = NEG_INF;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1548 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1549 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1550 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1551
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1552 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1553 write("next-minus...");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1554 pushContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1555 context.eMax = 999;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1556 context.eMin = -999;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1557 Decimal dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1558 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1559 dcm = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1560 expd = "0.999999999";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1561 assert(nextMinus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1562 dcm = "1E-1007";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1563 expd = "0E-1007";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1564 assert(nextMinus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1565 dcm = "-1.00000003";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1566 expd = "-1.00000004";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1567 assert(nextMinus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1568 dcm = "Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1569 expd = "9.99999999E+999";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1570 assert(nextMinus(dcm) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1571 popContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1572 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1573 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1574
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1575 public Decimal nextToward(const Decimal dcm1, const Decimal dcm2) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1576 Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1577 if (isInvalidOperation(dcm1, dcm2, result)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1578 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1579 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1580 int comp = icompare(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1581 if (comp < 0) return nextPlus(dcm1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1582 if (comp > 0) return nextMinus(dcm1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1583 result = copySign(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1584 round(result);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1585 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1586 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1587
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1588 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1589 write("next-toward..");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1590 DecimalContext save = context;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1591 Decimal dcm1, dcm2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1592 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1593 dcm1 = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1594 dcm2 = 2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1595 expd = "1.00000001";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1596 assert(nextToward(dcm1,dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1597 dcm1 = "-1E-1007";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1598 dcm2 = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1599 expd = "-0E-1007";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1600 assert(nextToward(dcm1,dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1601 dcm1 = "-1.00000003";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1602 dcm2 = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1603 expd = "-1.00000002";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1604 assert(nextToward(dcm1,dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1605 dcm1 = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1606 dcm2 = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1607 expd = "0.999999999";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1608 assert(nextToward(dcm1,dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1609 dcm1 = "1E-1007";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1610 dcm2 = -100;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1611 expd = "0E-1007";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1612 assert(nextToward(dcm1,dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1613 dcm1 = "-1.00000003";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1614 dcm2 = -10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1615 expd = "-1.00000004";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1616 assert(nextToward(dcm1,dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1617 dcm1 = "0.00";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1618 dcm2 = "-0.0000";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1619 expd = "-0.00";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1620 assert(nextToward(dcm1,dcm2) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1621 context = save;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1622 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1623 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1624
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1625 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1626 // comparison functions
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1627 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1628
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1629 /// returns true if the numbers have the same exponent.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1630 public bool sameQuantum(const Decimal x, const Decimal y) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1631 if (x.isNaN || y.isNaN) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1632 return x.isNaN && y.isNaN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1633 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1634 if (x.isInfinite || y.isInfinite) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1635 return x.isInfinite && y.isInfinite;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1636 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1637 return x.expo == y.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1638 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1639
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1640 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1641 write("same-quantum.");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1642 Decimal op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1643 Decimal op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1644 op1 = "2.17";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1645 op2 = "0.001";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1646 assert(!sameQuantum(op1, op2));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1647 op2 = "0.01";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1648 assert(sameQuantum(op1, op2));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1649 op2 = "0.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1650 assert(!sameQuantum(op1, op2));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1651 op2 = "1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1652 assert(!sameQuantum(op1, op2));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1653 op1 = "Inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1654 op2 = "Inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1655 assert(sameQuantum(op1, op2));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1656 op1 = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1657 op2 = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1658 assert(sameQuantum(op1, op2));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1659 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1660 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1661
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1662 public Decimal compare(const Decimal dcm1, const Decimal dcm2,
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1663 const bool signal = false) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1664 // sNaN is an invalid operand
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1665 if (dcm1.isSignaling && dcm2.isSignaling) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1666 return invalidOp();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1667 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1668 // qNaN is invalid if signal flag is set.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1669 if (signal && (dcm1.isNaN || dcm2.isNaN)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1670 return invalidOp();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1671 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1672 // NaN returns > any number, including NaN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1673 if (dcm1.isNaN) return ONE;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1674 if (dcm2.isNaN) return -ONE;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1675
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1676 if (dcm1.sign != dcm2.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1677 Decimal op1 = dcm1.sign ? -ONE : ONE;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1678 Decimal op2 = -op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1679 op1 = dcm1.isZero ? ZERO : op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1680 op2 = dcm2.isZero ? ZERO : op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1681 return op1 != op2 ? op1 : ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1682 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1683 int diff = (dcm1.expo + dcm1.digits) - (dcm2.expo + dcm2.digits);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1684 if (!dcm1.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1685 if (diff > 0) return ONE;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1686 if (diff < 0) return -ONE;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1687 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1688 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1689 if (diff > 0) return -ONE;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1690 if (diff < 0) return ONE;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1691 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1692 Decimal result = dcm1 - dcm2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1693 if (result.isZero) return ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1694 return result.sign ? -ONE : ONE;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1695 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1696
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1697 public int icompare(const Decimal dcm1, const Decimal dcm2) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1698 // sNaN is invalid operand
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1699 // NaN returns > any number, including NaN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1700 if (dcm1.isSignaling) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1701 invalidOp();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1702 return 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1703 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1704 if (dcm2.isSignaling) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1705 invalidOp();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1706 return -1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1707 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1708 // NaN returns > any number, including NaN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1709 if (dcm1.isNaN) return 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1710 if (dcm2.isNaN) return -1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1711
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1712 if (dcm1.sign != dcm2.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1713 int op1 = dcm1.sign ? -1 : 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1714 int op2 = -op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1715 op1 = dcm1.isZero ? 0 : op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1716 op2 = dcm2.isZero ? 0 : op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1717 return op1 != op2 ? op1 : 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1718 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1719 int diff = (dcm1.expo + dcm1.digits) - (dcm2.expo + dcm2.digits);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1720 if (!dcm1.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1721 if (diff > 0) return 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1722 if (diff < 0) return -1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1723 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1724 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1725 if (diff > 0) return -1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1726 if (diff < 0) return 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1727 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1728 Decimal result = dcm1 - dcm2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1729 if (result.isZero) return 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1730 return result.sign ? -1 : 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1731 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1732
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1733 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1734 write("compare......");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1735 Decimal op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1736 Decimal op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1737 int result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1738 op1 = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1739 op2 = "3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1740 result = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1741 assert(result == -1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1742 op1 = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1743 op2 = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1744 result = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1745 assert(result == 0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1746 op1 = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1747 op2 = "2.10";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1748 result = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1749 assert(result == 0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1750 op1 = "3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1751 op2 = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1752 result = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1753 assert(result == 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1754 op1 = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1755 op2 = "-3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1756 result = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1757 assert(result == 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1758 op1 = "-3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1759 op2 = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1760 result = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1761 assert(result == -1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1762 op1 = -3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1763 op2 = -4;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1764 result = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1765 assert(result == 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1766 op1 = -300;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1767 op2 = -4;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1768 result = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1769 assert(result == -1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1770 op1 = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1771 op2 = context.max;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1772 result = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1773 assert(result == -1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1774 op1 = -3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1775 op2 = -context.max;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1776 result = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1777 assert(result == 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1778
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1779 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1780 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1781
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1782 /// Returns 0 if the numbers are equal and have the same representation
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1783 public int compareTotal(const Decimal x, const Decimal y) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1784 if (x.sign != y.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1785 return x.sign ? -1 : 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1786 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1787 if (x.isQuiet || y.isQuiet) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1788 if (x.isQuiet && y.isQuiet) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1789 return 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1790 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1791 return x.isQuiet ? 1 : -1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1792 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1793 if (x.isSignaling || y.isSignaling) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1794 return 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1795 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1796 if (x.isInfinite || y.isInfinite) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1797 return 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1798 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1799 int diff = (x.expo + x.digits) - (y.expo + y.digits);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1800 if (diff > 0) return 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1801 if (diff < 0) return -1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1802 Decimal result = x - y;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1803 if (result.isZero) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1804 if (x.expo > y.expo) return 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1805 if (x.expo < y.expo) return -1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1806 return 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1807 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1808 return result.sign ? -1 : 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1809 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1810
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1811 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1812 write("comp-total...");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1813 Decimal op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1814 Decimal op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1815 int result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1816 op1 = "12.73";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1817 op2 = "127.9";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1818 result = compareTotal(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1819 assert(result == -1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1820 op1 = "-127";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1821 op2 = "12";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1822 result = compareTotal(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1823 assert(result == -1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1824 op1 = "12.30";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1825 op2 = "12.3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1826 result = compareTotal(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1827 assert(result == -1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1828 op1 = "12.30";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1829 op2 = "12.30";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1830 result = compareTotal(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1831 assert(result == 0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1832 op1 = "12.3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1833 op2 = "12.300";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1834 result = compareTotal(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1835 assert(result == 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1836 op1 = "12.3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1837 op2 = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1838 result = compareTotal(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1839 assert(result == -1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1840 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1841 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1842
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1843 int compareTotalMagnitude(const Decimal x, const Decimal y) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1844 return compareTotal(copyAbs(x), copyAbs(y));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1845 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1846
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1847 // TODO: this is where the need for flags comes in.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1848 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1849 * Returns the maximum of the two operands (or NaN).
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1850 * If either is an sNaN, or both are quiet NaNs, a NaN is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1851 * Otherwise, Any (finite or infinite) number is larger than a NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1852 * If they are not numerically equal, the larger is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1853 * If they are numerically equal:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1854 * 1) If the signs differ, the one with the positive sign is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1855 * 2) If they are positive, the one with the larger exponent is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1856 * 3) If they are negative, the one with the smaller exponent is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1857 * 4) Otherwise, they are indistinguishable; the first is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1858 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1859 Decimal max(const Decimal op1, const Decimal op2) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1860 // if both are NaNs or either is an sNan, return NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1861 if (op1.isNaN && op2.isNaN || op1.isSignaling || op2.isSignaling) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1862 return NaN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1863 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1864 // if one op is a quiet NaN return the other
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1865 if (op1.isQuiet || op2.isQuiet) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1866 return (op1.isQuiet) ? op2 : op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1867 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1868 // if the signs differ, return the unsigned operand
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1869 if (op1.sign != op2.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1870 return op1.sign ? op2 : op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1871 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1872 // if not numerically equal, return the larger
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1873 int comp = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1874 if (comp != 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1875 return comp > 0 ? op1 : op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1876 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1877 // if they have the same exponent they are identical, return either
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1878 if (op1.expo == op2.expo) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1879 return op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1880 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1881 // if they are non-negative, return the one with larger exponent.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1882 if (op1.sign == 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1883 return op1.expo > op2.expo ? op1 : op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1884 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1885 // else they are negative; return the one with smaller exponent.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1886 return op1.expo > op2.expo ? op2 : op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1887 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1888
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1889 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1890 write("max..........");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1891 Decimal op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1892 Decimal op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1893 op1 = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1894 op2 = 2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1895 assert(max(op1, op2) == op1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1896 op1 = -10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1897 op2 = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1898 assert(max(op1, op2) == op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1899 op1 = "1.0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1900 op2 = "1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1901 assert(max(op1, op2) == op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1902 op1 = "7";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1903 op2 = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1904 assert(max(op1, op2) == op1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1905 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1906 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1907
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1908 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1909 * Returns the minimum of the two operands (or NaN).
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1910 * If either is an sNaN, or both are quiet NaNs, a NaN is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1911 * Otherwise, Any (finite or infinite) number is smaller than a NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1912 * If they are not numerically equal, the smaller is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1913 * If they are numerically equal:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1914 * 1) If the signs differ, the one with the negative sign is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1915 * 2) If they are negative, the one with the larger exponent is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1916 * 3) If they are positive, the one with the smaller exponent is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1917 * 4) Otherwise, they are indistinguishable; the first is returned.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1918 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1919 Decimal min(const Decimal op1, const Decimal op2) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1920 // if both are NaNs or either is an sNan, return NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1921 if (op1.isNaN && op2.isNaN || op1.isSignaling || op2.isSignaling) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1922 /+ Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1923 result.flags = INVALID_OPERATION;+/
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1924 return NaN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1925 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1926 // if one op is a quiet NaN return the other
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1927 if (op1.isQuiet || op2.isQuiet) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1928 return (op1.isQuiet) ? op2 : op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1929 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1930 // if the signs differ, return the unsigned operand
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1931 if (op1.sign != op2.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1932 return op1.sign ? op1 : op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1933 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1934 // if not numerically equal, return the smaller
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1935 int comp = icompare(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1936 if (comp != 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1937 return comp < 0 ? op1 : op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1938 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1939 // if they have the same exponent they are identical, return either
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1940 if (op1.expo == op2.expo) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1941 return op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1942 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1943 // if they are non-negative, return the one with smaller exponent.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1944 if (op1.sign == 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1945 return op1.expo < op2.expo ? op1 : op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1946 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1947 // else they are negative; return the one with larger exponent.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1948 return op1.expo < op2.expo ? op2 : op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1949 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1950
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1951 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1952 write("min..........");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1953 Decimal op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1954 Decimal op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1955 op1 = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1956 op2 = 2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1957 assert(min(op1, op2) == op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1958 op1 = -10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1959 op2 = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1960 assert(min(op1, op2) == op1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1961 op1 = "1.0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1962 op2 = "1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1963 assert(min(op1, op2) == op1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1964 op1 = "7";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1965 op2 = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1966 assert(min(op1, op2) == op1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1967 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1968 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1969
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1970 //------------------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1971 //
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1972 // Binary Arithmetic Operations
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1973 //
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1974 //------------------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1975
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1976 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1977 * Adds two Decimal numbers.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1978 *
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1979 * This function corresponds to the "add and subtract" function
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1980 * in the General Decimal Arithmetic Specification and is the basis
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1981 * for the opAdd and opSub functions for the Decimal struct.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1982 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1983 Decimal add(const Decimal augend, const Decimal addend) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1984
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1985 Decimal sum;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1986 // check for NaN operand(s)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1987 if (isInvalidOperation(augend, addend, sum)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1988 return sum;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1989 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1990 // if both operands are infinite
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1991 if (augend.isInfinite && addend.isInfinite) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1992 // (+inf) + (-inf) => invalid operation
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1993 if (augend.sign != addend.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1994 return invalidOp();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1995 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1996 // both infinite with same sign
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1997 return augend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1998 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
1999
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2000 /+ if (isInvalidAddition(augend, addend, sum)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2001 return sum;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2002 }+/
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2003 // TODO: is it okay to return the operand? is a copy implied?
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2004 // only augend is infinite,
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2005 if (augend.isInfinite) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2006 return augend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2007 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2008 // only addend is infinite
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2009 if (addend.isInfinite) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2010 return addend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2011 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2012
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2013 // align the operands
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2014 alignOps(augend, addend);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2015
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2016 // add(0, 0)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2017 if (augend.isZero && addend.isZero) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2018 sum = augend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2019 sum.sign = augend.sign && addend.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2020 return sum;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2021 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2022
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2023 // at this point, the result will be finite and not zero
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2024 // (before rounding)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2025 sum.clear();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2026
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2027 // if operands have the same sign...
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2028 if (augend.sign == addend.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2029 sum.ceff = augend.ceff + addend.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2030 sum.sign = augend.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2031 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2032 // ...else operands have different signs
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2033 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2034 sum.ceff = augend.ceff - addend.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2035 sum.sign = augend.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2036 if (sum.ceff < BIG_ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2037 sum.ceff = -sum.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2038 sum.sign = !sum.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2039 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2040 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2041 // set the number of digits and the exponent
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2042 sum.digits = numDigits(sum.ceff, augend.digits);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2043 sum.expo = augend.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2044
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2045 // round the result
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2046 round(sum);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2047 return sum;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2048 } // end add(augend, addend)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2049
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2050 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2051 * Subtracts two Decimal numbers.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2052 *
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2053 * This function corresponds to the "add and subtract" function
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2054 * in the General Decimal Arithmetic Specification and is the basis
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2055 * for the opAdd and opSub functions for the Decimal struct.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2056 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2057 Decimal subtract(const Decimal minuend, const Decimal subtrahend) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2058 return add(minuend, copyNegate(subtrahend));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2059 } // end subtract(minuend, subtrahend)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2060
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2061 // TODO: these tests need to be cleaned up to rely less on strings
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2062 // and to check the NaN, Inf combinations better.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2063 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2064 write("add..........");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2065 Decimal dcm1 = Decimal("12");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2066 Decimal dcm2 = Decimal("7.00");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2067 Decimal sum = add(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2068 assert(sum.toString() == "19.00");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2069 dcm1 = Decimal("1E+2");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2070 dcm2 = Decimal("1E+4");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2071 sum = add(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2072 assert(sum.toString() == "1.01E+4");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2073 dcm1 = Decimal("1.3");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2074 dcm2 = Decimal("1.07");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2075 sum = subtract(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2076 assert(sum.toString() == "0.23");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2077 dcm2 = Decimal("1.30");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2078 sum = subtract(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2079 assert(sum.toString() == "0.00");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2080 dcm2 = Decimal("2.07");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2081 sum = subtract(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2082 assert(sum.toString() == "-0.77");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2083 dcm1 = "Inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2084 dcm2 = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2085 sum = add(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2086 assert(sum.toString() == "Infinity");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2087 dcm1 = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2088 dcm2 = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2089 sum = add(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2090 assert(sum.isQuiet);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2091 dcm2 = "Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2092 sum = add(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2093 assert(sum.isQuiet);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2094 dcm1 = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2095 sum = subtract(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2096 assert(sum.toString() == "-Infinity");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2097 dcm1 = "-0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2098 dcm2 = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2099 sum = subtract(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2100 assert(sum.toString() == "-0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2101 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2102 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2103
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2104 Decimal multiply(const Decimal multiplier, const Decimal multiplicand) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2105
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2106 Decimal product;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2107 if (isInvalidMultiplication(multiplier, multiplicand, product)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2108 return product;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2109 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2110 if (multiplier.isInfinite || multiplicand.isInfinite) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2111 product = Decimal.infinity;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2112 product.sign = multiplier.sign ^ multiplicand.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2113 return product;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2114 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2115 product.clear();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2116 product.ceff = multiplier.ceff * multiplicand.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2117 product.expo = multiplier.expo + multiplicand.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2118 product.sign = multiplier.sign ^ multiplicand.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2119 product.digits = numDigits(product.ceff, multiplier.digits + multiplicand.digits);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2120 round(product);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2121 return product;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2122 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2123
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2124 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2125 write("multiply.....");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2126 Decimal op1, op2, result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2127 op1 = Decimal("1.20");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2128 op2 = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2129 result = op1 * op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2130 assert(result.toString() == "3.60");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2131 op1 = 7;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2132 result = op1 * op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2133 assert(result.toString() == "21");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2134 op1 = Decimal("0.9");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2135 op2 = Decimal("0.8");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2136 result = op1 * op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2137 assert(result.toString() == "0.72");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2138 op1 = Decimal("0.9");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2139 op2 = Decimal("-0.0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2140 result = op1 * op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2141 assert(result.toString() == "-0.00");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2142 op1 = Decimal(654321);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2143 op2 = Decimal(654321);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2144 result = op1 * op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2145 assert(result.toString() == "4.28135971E+11");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2146 op1 = -1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2147 op2 = "Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2148 result = op1 * op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2149 assert(result.toString() == "-Infinity");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2150 op1 = -1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2151 op2 = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2152 result = op1 * op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2153 assert(result.toString() == "-0");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2154 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2155 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2156
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2157 Decimal fma(const Decimal multiplier, const Decimal multiplicand,
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2158 const Decimal addend) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2159 Decimal product;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2160 if (isInvalidMultiplication(multiplier, multiplicand, product)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2161 return product;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2162 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2163 product.clear();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2164 product.ceff = multiplier.ceff * multiplicand.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2165 product.expo = multiplier.expo + multiplicand.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2166 product.sign = multiplier.sign ^ multiplicand.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2167 product.digits = numDigits(product.ceff, multiplier.digits + multiplicand.digits);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2168 return add(product, addend);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2169 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2170
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2171 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2172 write("fma..........");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2173 Decimal op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2174 Decimal op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2175 Decimal op3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2176 Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2177 op1 = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2178 op2 = 5;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2179 op3 = 7;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2180 result = (fma(op1, op2, op3));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2181 assert(result == Decimal(22));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2182 op1 = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2183 op2 = -5;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2184 op3 = 7;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2185 result = (fma(op1, op2, op3));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2186 assert(result == Decimal(-8));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2187 op1 = "888565290";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2188 op2 = "1557.96930";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2189 op3 = "-86087.7578";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2190 result = (fma(op1, op2, op3));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2191 assert(result == Decimal("1.38435736E+12"));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2192 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2193 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2194
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2195 bool isZeroDividend(const Decimal dividend, const Decimal divisor,
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2196 Decimal quotient) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2197 if (dividend.isZero()) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2198 quotient.spval = SpVal.ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2199 quotient.ceff = BIG_ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2200 quotient.expo = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2201 quotient.digits = dividend.digits;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2202 quotient.sign = dividend.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2203 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2204 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2205 return false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2206 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2207
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2208 Decimal divide(const Decimal dividend, const Decimal divisor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2209
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2210 Decimal quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2211 if (isInvalidDivision(dividend, divisor, quotient)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2212 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2213 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2214 if (isZeroDividend(dividend, divisor, quotient)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2215 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2216 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2217 quotient.clear();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2218
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2219 Decimal temp = dividend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2220 int adjust = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2221 while (temp.ceff < divisor.ceff) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2222 temp.ceff *= 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2223 adjust++;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2224 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2225 bool complete = false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2226 while (!complete) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2227 // repeated subtraction
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2228 while (divisor.ceff <= temp.ceff) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2229 temp.ceff -= divisor.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2230 quotient.ceff++;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2231 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2232 // check for done
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2233 if (temp.ceff == 0 && adjust >= 0
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2234 || numDigits(quotient.ceff, 1) == context.precision + 2) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2235 complete = true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2236 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2237 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2238 // bump the quotient and temp by 10
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2239 quotient.ceff *= 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2240 temp.ceff *= 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2241 adjust++;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2242 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2243 quotient.digits = numDigits(quotient.ceff, context.precision);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2244 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2245 quotient.expo = temp.expo - divisor.expo - adjust;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2246 quotient.sign = temp.sign ^ divisor.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2247 round(quotient);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2248 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2249 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2250
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2251 Decimal edivide(const Decimal dividend, const Decimal divisor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2252 Decimal quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2253 if (isInvalidDivision(dividend, divisor, quotient)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2254 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2255 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2256 if (isZeroDividend(dividend, divisor, quotient)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2257 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2258 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2259 quotient.clear();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2260 Decimal denom = dividend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2261 Decimal numer = divisor;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2262 // align operands
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2263 int diff = denom.expo - numer.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2264 if (diff < 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2265 numer.ceff *= pow10(-diff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2266 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2267 if (diff > 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2268 numer.ceff *= pow10(diff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2269 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2270 numer.digits = numDigits(numer.ceff, 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2271 denom.digits = numDigits(denom.ceff, 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2272 int shift = 2 + context.precision - denom.digits + numer.digits;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2273 if (shift > 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2274 denom.ceff *= pow10(shift);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2275 denom.expo -= shift;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2276 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2277 quotient.ceff = denom.ceff / numer.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2278 quotient.expo = denom.expo - numer.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2279 quotient.sign = denom.sign ^ numer.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2280 quotient.digits = numDigits(quotient.ceff, context.precision);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2281 round(quotient);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2282 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2283 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2284
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2285 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2286 write("divide.......");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2287 Decimal dcm1, dcm2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2288 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2289 dcm1 = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2290 dcm2 = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2291 Decimal quotient = edivide(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2292 expd = "0.333333333";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2293 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2294 assert(quotient.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2295 dcm1 = 2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2296 dcm2 = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2297 quotient = edivide(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2298 expd = "0.666666667";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2299 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2300 dcm1 = 5;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2301 dcm2 = 2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2302 quotient = divide(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2303 expd = "2.5";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2304 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2305 assert(quotient.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2306 dcm1 = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2307 dcm2 = 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2308 expd = 0.1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2309 quotient = divide(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2310 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2311 assert(quotient.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2312 dcm1 = "8.00";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2313 dcm2 = 2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2314 expd = "4.00";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2315 quotient = divide(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2316 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2317 assert(quotient.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2318 dcm1 = "2.400";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2319 dcm2 = "2.0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2320 expd = "1.20";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2321 quotient = divide(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2322 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2323 assert(quotient.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2324 dcm1 = 1000;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2325 dcm2 = 100;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2326 expd = 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2327 quotient = divide(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2328 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2329 assert(quotient.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2330 dcm2 = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2331 quotient = divide(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2332 expd = 1000;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2333 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2334 assert(quotient.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2335 dcm1 = "2.40E+6";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2336 dcm2 = 2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2337 expd = "1.20E+6";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2338 quotient = divide(dcm1, dcm2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2339 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2340 assert(quotient.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2341 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2342 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2343
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2344 Decimal divideInteger(const Decimal dividend, const Decimal divisor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2345 Decimal quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2346 if (isInvalidDivision(dividend, divisor, quotient)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2347 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2348 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2349 if (isZeroDividend(dividend, divisor, quotient)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2350 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2351 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2352 quotient.clear();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2353 Decimal denom = dividend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2354 Decimal numer = divisor;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2355 // align operands
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2356 int diff = denom.expo - numer.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2357 if (diff < 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2358 numer.ceff *= pow10(-diff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2359 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2360 if (diff > 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2361 denom.ceff *= pow10(diff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2362 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2363 quotient.ceff = denom.ceff / numer.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2364 quotient.expo = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2365 quotient.sign = denom.sign ^ numer.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2366 quotient.digits = numDigits(quotient.ceff, context.precision);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2367 if (quotient.ceff == 0) quotient.spval = SpVal.ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2368 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2369 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2370
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2371 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2372 write("div-int......");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2373 Decimal dividend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2374 Decimal divisor;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2375 Decimal quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2376 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2377 dividend = 2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2378 divisor = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2379 quotient = divideInteger(dividend, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2380 expd = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2381 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2382 dividend = 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2383 quotient = divideInteger(dividend, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2384 expd = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2385 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2386 dividend = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2387 divisor = "0.3";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2388 quotient = divideInteger(dividend, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2389 assert(quotient == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2390 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2391 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2392
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2393 Decimal remainder(const Decimal dividend, const Decimal divisor) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2394 Decimal quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2395 if (isInvalidDivision(dividend, divisor, quotient)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2396 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2397 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2398 if (isZeroDividend(dividend, divisor, quotient)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2399 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2400 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2401 quotient = dividend - divisor * divideInteger(dividend, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2402 return quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2403 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2404
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2405 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2406 write("remainder....");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2407 Decimal dividend;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2408 Decimal divisor;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2409 Decimal quotient;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2410 Decimal expected;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2411 dividend = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2412 divisor = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2413 quotient = remainder(dividend, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2414 expected = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2415 assert(quotient == expected);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2416 dividend = 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2417 quotient = remainder(dividend, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2418 expected = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2419 assert(quotient == expected);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2420 dividend = -10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2421 quotient = remainder(dividend, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2422 expected = -1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2423 assert(quotient == expected);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2424 dividend = 10.2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2425 divisor = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2426 quotient = remainder(dividend, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2427 expected = "0.2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2428 assert(quotient == expected);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2429 dividend = 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2430 divisor = 0.3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2431 quotient = remainder(dividend, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2432 expected = "0.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2433 assert(quotient == expected);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2434 dividend = 3.6;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2435 divisor = 1.3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2436 quotient = remainder(dividend, divisor);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2437 expected = "1.0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2438 assert(quotient == expected);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2439 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2440 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2441
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2442 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2443 // rounding
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2444 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2445
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2446 public Decimal rint(const Decimal dec){
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2447 if (dec.isSignaling) return invalidOp();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2448 if (dec.isSpecial) return dec;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2449 if (dec.expo >= 0) return dec;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2450 pushContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2451 context.precision = dec.digits;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2452 Decimal result = quantize(dec, ONE);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2453 popContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2454 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2455 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2456
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2457 public Decimal nearbyint(const Decimal dec){
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2458 // this operation shouldn't affect the inexact or rounded flags
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2459 // so we'll save them in case they were already set.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2460 bool inexact = context.getFlag(INEXACT);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2461 bool rounded = context.getFlag(ROUNDED);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2462 Decimal result = rint(dec);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2463 context.setFlag(INEXACT, inexact);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2464 context.setFlag(ROUNDED, rounded);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2465 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2466 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2467
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2468 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2469 write("rnd-int-ex...");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2470 Decimal dec;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2471 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2472 Decimal actual;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2473 dec = 2.1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2474 expd = 2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2475 actual = rint(dec);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2476 assert(actual == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2477 dec = 100;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2478 expd = 100;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2479 assert(rint(dec) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2480 assert(rint(dec).toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2481 dec = "100.0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2482 assert(rint(dec) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2483 assert(rint(dec).toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2484 dec = "101.5";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2485 expd = 102;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2486 assert(rint(dec) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2487 assert(rint(dec).toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2488 dec = "-101.5";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2489 expd = -102;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2490 assert(rint(dec) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2491 assert(rint(dec).toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2492 dec = "10E+5";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2493 expd = "1.0E+6";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2494 assert(rint(dec) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2495 assert(rint(dec).toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2496 dec = "7.89E+77";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2497 expd = "7.89E+77";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2498 assert(rint(dec) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2499 assert(rint(dec).toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2500 dec = "-Inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2501 expd = "-Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2502 assert(rint(dec) == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2503 assert(rint(dec).toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2504 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2505 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2506
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2507 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2508 * Clips the coefficient of the number to the specified precision.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2509 * Returns the remainder for adjustments based on rounding mode.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2510 * Sets the ROUNDED and INEXACT flags.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2511 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2512 private BigInt shorten(ref Decimal number) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2513 BigInt remainder = BIG_ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2514 int diff = number.digits - context.precision;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2515 if (diff <= 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2516 return remainder;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2517 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2518 context.setFlag(ROUNDED);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2519 if (context.precision == 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2520 remainder = number.ceff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2521 number.ceff = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2522 number.digits = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2523 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2524 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2525 BigInt divisor = pow10(diff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2526 remainder = number.ceff % divisor;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2527 number.ceff /= divisor;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2528 number.digits = context.precision;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2529 number.expo += diff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2530 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2531 if (remainder != BIG_ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2532 context.setFlag(INEXACT);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2533 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2534 return remainder;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2535 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2536
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2537 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2538 * Increments the coefficient by 1. If this causes an overflow, divides by 10.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2539 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2540 private void increment(ref BigInt number) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2541 number++;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2542 if (lastDigit(number) == 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2543 number /= 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2544 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2545 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2546
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2547 // TODO: need to signal inexact and rounded.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2548 private void roundByMode(ref Decimal number) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2549 BigInt remainder = shorten(number);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2550
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2551 // if the rounded flag is not set by the shorten operation, return
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2552 if (!context.getFlag(ROUNDED)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2553 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2554 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2555 // if the remainder is zero, return
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2556 if (remainder == BIG_ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2557 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2558 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2559
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2560 switch (context.mode) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2561 case Rounding.DOWN:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2562 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2563 case Rounding.HALF_UP:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2564 if (firstDigit(remainder) >= 5) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2565 increment(number.ceff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2566 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2567 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2568 case Rounding.HALF_EVEN:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2569 BigInt test = 5 * pow10(numDigits(remainder,1)-1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2570 int result = remainder.opCmp(test);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2571 if (result > 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2572 increment(number.ceff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2573 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2574 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2575 if (result < 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2576 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2577 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2578 // if last digit is odd...
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2579 if (lastDigit(number.ceff) & 1 == 1) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2580 increment(number.ceff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2581 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2582 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2583 case Rounding.CEILING:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2584 if (!number.sign && remainder != BIG_ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2585 increment(number.ceff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2586 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2587 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2588 case Rounding.FLOOR:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2589 if (number.sign && remainder != BIG_ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2590 increment(number.ceff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2591 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2592 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2593 case Rounding.HALF_DOWN:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2594 if (firstDigit(remainder) > 5) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2595 increment(number.ceff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2596 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2597 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2598 case Rounding.UP:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2599 if (remainder != BIG_ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2600 increment(number.ceff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2601 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2602 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2603 } // end switch(mode)
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2604 } // end roundByMode()
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2605
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2606 public void round(ref Decimal number) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2607 if (!number.isFinite) return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2608
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2609 context.clearFlags();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2610 // check for subnormal
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2611 bool subnormal = false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2612 if (number.isSubnormal()) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2613 context.setFlag(SUBNORMAL);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2614 subnormal = true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2615 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2616
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2617 // check for overflow
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2618 if (number.overflow()) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2619 context.setFlag(OVERFLOW);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2620 switch (context.mode) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2621 case Rounding.HALF_UP:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2622 case Rounding.HALF_EVEN:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2623 case Rounding.HALF_DOWN:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2624 case Rounding.UP:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2625 bool sign = number.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2626 number = POS_INF;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2627 number.sign = sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2628 break;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2629 case Rounding.DOWN:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2630 bool sign = number.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2631 number = context.max;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2632 number.sign = sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2633 break;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2634 case Rounding.CEILING:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2635 if (number.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2636 number = context.max;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2637 number.sign = true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2638 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2639 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2640 number = POS_INF;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2641 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2642 break;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2643 case Rounding.FLOOR:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2644 if (number.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2645 number = NEG_INF;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2646 } else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2647 number = context.max;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2648 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2649 break;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2650 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2651 context.setFlag(INEXACT);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2652 context.setFlag(ROUNDED);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2653 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2654 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2655 roundByMode(number);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2656 // check for underflow
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2657 if (number.isSubnormal /+&& number.isInexact+/) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2658 context.setFlag(SUBNORMAL);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2659 int diff = context.eTiny - number.adjustedExponent();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2660 if (diff > number.digits) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2661 number.ceff = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2662 number.expo = context.eTiny;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2663 } else if (diff > 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2664 writeln("We got a tiny one!");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2665 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2666 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2667 // check for zero
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2668 if (number.spval == SpVal.CLEAR && number.ceff == BIG_ZERO) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2669 number.spval = SpVal.ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2670 // subnormal rounding to zero == clamped
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2671 // Spec. p. 51
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2672 if (subnormal) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2673 context.setFlag(CLAMPED);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2674 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2675 return;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2676 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2677 } // end round()
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2678
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2679 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2680 write("round........");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2681 Decimal before = Decimal(1234567890);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2682 Decimal after = before;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2683 pushContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2684 context.precision = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2685 round(after);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2686 assert(after.toString() == "1.23E+9");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2687 after = before;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2688 context.precision = 4;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2689 round(after);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2690 assert(after.toString() == "1.235E+9");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2691 after = before;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2692 context.precision = 5;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2693 round(after);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2694 assert(after.toString() == "1.2346E+9");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2695 after = before;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2696 context.precision = 6;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2697 round(after);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2698 assert(after.toString() == "1.23457E+9");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2699 after = before;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2700 context.precision = 7;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2701 round(after);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2702 assert(after.toString() == "1.234568E+9");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2703 after = before;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2704 context.precision = 8;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2705 round(after);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2706 assert(after.toString() == "1.2345679E+9");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2707 before = "1235";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2708 after = before;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2709 context.precision = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2710 round(after);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2711 assert(after.toAbstract() == "[0,124,1]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2712 before = "12359";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2713 after = before;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2714 context.precision = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2715 round(after);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2716 assert(after.toAbstract() == "[0,124,2]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2717 before = "1245";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2718 after = before;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2719 context.precision = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2720 round(after);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2721 assert(after.toAbstract() == "[0,124,1]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2722 before = "12459";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2723 after = before;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2724 context.precision = 3;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2725 round(after);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2726 assert(after.toAbstract() == "[0,125,2]");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2727 popContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2728 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2729 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2730
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2731 public void setDigits(ref Decimal number) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2732 int diff = number.digits - context.precision;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2733 if (diff > 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2734 round(number);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2735 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2736 else if (diff < 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2737 number.ceff *= pow10(-diff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2738 number.expo += diff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2739 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2740 number.digits = context.precision;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2741 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2742
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2743 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2744 * Returns the number which is equal in value and sign
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2745 * to the first operand and which has its exponent set
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2746 * to be equal to the exponent of the second operand.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2747 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2748 // TODO: this has unusual flag rules
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2749 Decimal quantize(const Decimal dcm1, const Decimal dcm2) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2750 Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2751 if (isInvalidOperation(dcm1, dcm2, result)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2752 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2753 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2754 if (dcm1.isInfinite != dcm2.isInfinite() ||
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2755 dcm2.isInfinite != dcm1.isInfinite()) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2756 return invalidOp();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2757 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2758 if (dcm1.isInfinite() && dcm2.isInfinite()) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2759 return dcm1.dup;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2760 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2761 result = dcm1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2762 int diff = dcm1.expo - dcm2.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2763 if (diff == 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2764 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2765 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2766 if (diff > 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2767 result.ceff *= pow10(diff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2768 result.digits += diff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2769 result.expo = dcm2.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2770 if (result.digits > context.precision) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2771 result = NaN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2772 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2773 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2774 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2775 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2776 pushContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2777 context.precision =
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2778 -diff > dcm1.digits ? 0 : dcm1.digits + diff;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2779 round(result);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2780 result.expo = dcm2.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2781 popContext();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2782 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2783 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2784 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2785
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2786 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2787 write("quantize.....");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2788 Decimal op1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2789 Decimal op2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2790 Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2791 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2792 string str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2793 op1 = "2.17";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2794 op2 = "0.001";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2795 expd = "2.170";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2796 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2797 assert(result == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2798 op1 = "2.17";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2799 op2 = "0.01";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2800 expd = "2.17";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2801 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2802 assert(result == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2803 op1 = "2.17";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2804 op2 = "0.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2805 expd = "2.2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2806 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2807 assert(result == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2808 op1 = "2.17";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2809 op2 = "1e+0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2810 expd = "2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2811 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2812 assert(result == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2813 op1 = "2.17";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2814 op2 = "1e+1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2815 expd = "0E+1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2816 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2817 assert(result.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2818 op1 = "-Inf";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2819 op2 = "Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2820 expd = "-Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2821 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2822 assert(result == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2823 op1 = "2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2824 op2 = "Infinity";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2825 expd = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2826 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2827 assert(result.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2828 op1 = "-0.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2829 op2 = "1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2830 expd = "-0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2831 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2832 assert(result.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2833 op1 = "-0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2834 op2 = "1e+5";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2835 expd = "-0E+5";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2836 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2837 assert(result.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2838 op1 = "+35236450.6";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2839 op2 = "1e-2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2840 expd = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2841 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2842 assert(result.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2843 op1 = "-35236450.6";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2844 op2 = "1e-2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2845 expd = "NaN";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2846 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2847 assert(result.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2848 op1 = "217";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2849 op2 = "1e-1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2850 expd = "217.0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2851 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2852 assert(result.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2853 op1 = "217";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2854 op2 = "1e+0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2855 expd = "217";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2856 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2857 assert(result.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2858 op1 = "217";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2859 op2 = "1e+1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2860 expd = "2.2E+2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2861 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2862 assert(result.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2863 op1 = "217";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2864 op2 = "1e+2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2865 expd = "2E+2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2866 result = quantize(op1, op2);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2867 assert(result.toString() == expd.toString());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2868 assert(result == expd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2869 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2870 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2871
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2872 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2873 * Reduces operand to simplest form. All trailing zeros are removed.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2874 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2875 // TODO: has non-standard flag setting
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2876 Decimal reduce(const Decimal dcm) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2877 Decimal result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2878 if (isInvalidOperation(dcm, result)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2879 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2880 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2881 result = dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2882 if (!result.isFinite()) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2883 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2884 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2885 BigInt temp = result.ceff % 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2886 while (result.ceff != 0 && temp == 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2887 result.expo++;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2888 result.ceff = result.ceff / 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2889 temp = result.ceff % 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2890 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2891 if (result.ceff == 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2892 result.spval = SpVal.ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2893 result.expo = 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2894 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2895 result.digits = numDigits(result.ceff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2896 return result;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2897 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2898
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2899 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2900 write("reduce.......");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2901 Decimal dec;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2902 Decimal red;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2903 string str;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2904 dec = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2905 str = "2.1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2906 red = reduce(dec);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2907 assert(red.toString() == str);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2908 dec = "-2.0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2909 str = "-2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2910 red = reduce(dec);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2911 assert(red.toString() == str);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2912 dec = "1.200";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2913 str = "1.2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2914 red = reduce(dec);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2915 assert(red.toString() == str);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2916 dec = "-120";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2917 str = "-1.2E+2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2918 red = reduce(dec);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2919 assert(red.toString() == str);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2920 dec = "120.00";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2921 str = "1.2E+2";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2922 red = reduce(dec);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2923 assert(red.toString() == str);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2924 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2925 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2926
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2927 private:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2928
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2929 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2930 * Sets the invalid-operation flag and
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2931 * returns a quiet NaN.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2932 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2933 Decimal invalidOp() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2934 context.flags |= INVALID_OPERATION;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2935 return NaN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2936 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2937
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2938 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2939 * aligns the two operands by raising the smaller exponent
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2940 * to the value of the larger exponent, and adjusting the
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2941 * coefficient so the value remains the same.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2942 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2943 void alignOps(ref Decimal op1, ref Decimal op2) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2944 int diff = op1.expo - op2.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2945 if (diff > 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2946 op1.ceff *= pow10(diff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2947 op1.expo = op2.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2948 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2949 else if (diff < 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2950 op2.ceff *= pow10(-diff);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2951 op2.expo = op1.expo;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2952 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2953 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2954
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2955 /*
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2956 * "The result of any arithmetic operation which has an operand
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2957 * which is a NaN (a quiet NaN or a signaling NaN) is [s,qNaN]
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2958 * or [s,qNaN,d]. The sign and any diagnostic information is copied
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2959 * from the first operand which is a signaling NaN, or if neither is
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2960 * signaling then from the first operand which is a NaN."
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2961 * -- General Decimal Arithmetic Specification, p. 24
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2962 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2963 bool isInvalidOperation(const Decimal dcm1, const Decimal dcm2,
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2964 ref Decimal result) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2965 // if either operand is an sNaN...
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2966 if (dcm1.isSignaling || dcm2.isSignaling) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2967 // set the result to the first sNaN operand
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2968 result = dcm1.isSignaling ? dcm1 : dcm2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2969 // retain sign and payload; convert to qNaN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2970 result.spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2971 // flag the invalid operation
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2972 context.flags |= INVALID_OPERATION;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2973 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2974 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2975 // ...else if either operand is a qNaN...
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2976 if (dcm1.isQuiet || dcm2.isQuiet) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2977 // set the result to the first qNaN operand
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2978 result = dcm1.isQuiet ? dcm1 : dcm2;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2979 // flag the invalid operation
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2980 context.flags |= INVALID_OPERATION;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2981 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2982 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2983 // ...otherwise, no flags are set and result is unchanged
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2984 return false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2985 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2986
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2987 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2988 write("invalid......");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2989 Decimal dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2990 Decimal expd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2991 Decimal actual;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2992
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2993 dcm = "sNaN123";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2994 expd = "NaN123";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2995 actual = abs(dcm);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2996 assert(actual.isQuiet);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2997 assert(context.flags && INVALID_OPERATION);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2998 assert(actual.toAbstract == expd.toAbstract);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
2999 dcm = "NaN123";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3000 actual = abs(dcm);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3001 assert(actual.isQuiet);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3002 assert(context.flags && INVALID_OPERATION);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3003 assert(actual.toAbstract == expd.toAbstract);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3004
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3005 dcm = "sNaN123";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3006 expd = "NaN123";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3007 actual = -dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3008 assert(actual.isQuiet);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3009 assert(context.flags && INVALID_OPERATION);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3010 assert(actual.toAbstract == expd.toAbstract);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3011 dcm = "NaN123";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3012 actual = -dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3013 assert(actual.isQuiet);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3014 assert(context.flags && INVALID_OPERATION);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3015 assert(actual.toAbstract == expd.toAbstract);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3016 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3017 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3018
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3019 /*
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3020 * "The result of any arithmetic operation which has an operand
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3021 * which is a NaN (a quiet NaN or a signaling NaN) is [s,qNaN]
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3022 * or [s,qNaN,d]. The sign and any diagnostic information is copied
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3023 * from the first operand which is a signaling NaN, or if neither is
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3024 * signaling then from the first operand which is a NaN."
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3025 * -- General Decimal Arithmetic Specification, p. 24
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3026 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3027 bool isInvalidOperation(const Decimal dcm, ref Decimal result) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3028 // if the operand is an sNaN...
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3029 if (dcm.isSignaling) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3030 // set the result to the sNaN operand
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3031 result = dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3032 // retain sign and payload; convert to qNaN
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3033 result.spval = SpVal.QNAN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3034 // flag the invalid operation
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3035 context.flags |= INVALID_OPERATION;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3036 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3037 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3038 // ...else if the operand is a qNaN...
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3039 if (dcm.isQuiet) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3040 // set the result to the qNaN operand
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3041 result = dcm;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3042 // flag the invalid operation
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3043 context.flags |= INVALID_OPERATION;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3044 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3045 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3046 // ...otherwise, no flags are set and result is unchanged
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3047 return false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3048 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3049
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3050 // TODO: add unit tests here for operations that apply
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3051 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3052
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3053 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3054
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3055 /+/*
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3056 * -- General Decimal Arithmetic Specification, p. 52, "Invalid operation"
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3057 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3058 bool isInvalidAddition(Decimal op1, Decimal op2, ref Decimal result) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3059 if (isInvalidOperation(op1, op2, result)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3060 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3061 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3062 // if both operands are infinite
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3063 if (op1.isInfinite && op2.isInfinite) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3064 // (+inf) + (-inf) => invalid operation
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3065 if (op1.sign != op2.sign) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3066 result = invalidOp();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3067 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3068 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3069 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3070 return false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3071 }+/
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3072
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3073 /*
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3074 * -- General Decimal Arithmetic Specification, p. 52, "Invalid operation"
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3075 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3076 bool isInvalidMultiplication(Decimal op1, Decimal op2, ref Decimal result) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3077 if (isInvalidOperation(op1, op2, result)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3078 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3079 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3080 if (op1.isZero && op2.isInfinite || op1.isInfinite && op2.isZero) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3081 result = NaN;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3082 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3083 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3084 return false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3085 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3086
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3087 /*
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3088 * -- General Decimal Arithmetic Specification, p. 52, "Invalid operation"
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3089 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3090 bool isInvalidDivision(Decimal dividend, Decimal divisor, ref Decimal quotient) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3091 if (isInvalidOperation(dividend, divisor, quotient)) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3092 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3093 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3094 if (divisor.isZero()) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3095 if (dividend.isZero()) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3096 quotient = invalidOp();
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3097 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3098 else {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3099 quotient.spval = SpVal.INF;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3100 context.flags |= DIVISION_BY_ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3101 quotient.ceff = BIG_ZERO;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3102 quotient.sign = dividend.sign ^ divisor.sign;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3103 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3104 return true;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3105 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3106 return false;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3107 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3108
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3109 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3110 // unit tests
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3111 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3112
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3113 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3114 // additions to BigInt
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3115 //--------------------------------
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3116
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3117 private:
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3118 static immutable BigInt BIG_ZERO = { [0] };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3119 static immutable BigInt BIG_ONE = { [1] };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3120 static immutable BigInt BIG_FIVE = { [5] };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3121 static immutable BigInt BIG_TEN = { [10] };
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3122
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3123 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3124 * Returns the number of decimal digits in BigInt value.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3125 * There are probably significant efficiency gains available.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3126 **/
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3127 uint numDigits(const BigInt big, int n = 1) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3128 if (big == 0) return 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3129 if (n <= 0) n = 1;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3130 int m = n;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3131 while (big < pow10(m-1)) m--;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3132 if (m != n) return m;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3133 while (big >= pow10(m)) m++;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3134 return m;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3135 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3136
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3137 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3138 * Returns a BigInt with the value of 10 raised to the specified power.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3139 * There are probably significant efficiency gains available.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3140 **/
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3141 public BigInt pow10(uint power) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3142 static immutable int BILLION = 1000000000;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3143 static immutable int array[10] =
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3144 [ 1, 10, 100, 1000, 10000, 100000, 1000000,
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3145 10000000, 100000000, BILLION ];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3146
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3147 if (power < 10) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3148 return BigInt(array[power]);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3149 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3150 BigInt big = BigInt(BILLION);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3151 power -= 9;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3152 int quo = power / 9;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3153 int rem = power % 9;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3154 for (int i = 0; i < quo; i++) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3155 big *= BILLION;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3156 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3157 return big * array[rem];
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3158 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3159
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3160 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3161 * Returns the first decimal digit of the specified BigInt.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3162 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3163 uint firstDigit(BigInt big) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3164 uint digits = numDigits(big, 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3165 if (digits == 0) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3166 return 0;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3167 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3168 BigInt bfd = big / pow10(digits - 1);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3169 uint ifd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3170 bfd.castTo(ifd);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3171 return ifd;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3172 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3173
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3174 /**
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3175 * Returns the last decimal digit of the specified BigInt.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3176 */
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3177 uint lastDigit(BigInt big) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3178 return big % 10;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3179 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3180
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3181 unittest {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3182 write("bigint.......");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3183 string str = "1";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3184 BigInt big = pow10(0);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3185 assert(str == big.toString);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3186 for (int i = 1; i < 35; i++) {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3187 str ~= "0";
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3188 big = pow10(i);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3189 assert(str == big.toString);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3190 assert(numDigits(big) == str.length);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3191 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3192 writeln("passed");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3193 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3194
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3195 public void main() {
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3196 writeln("Hello, world!");
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3197 /+ writeln("eTiny = ", context.eTiny);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3198 writeln("tiny min = ", Decimal(1, context.eTiny));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3199 writeln("tiny min = ", Decimal(1, context.eTiny - 1));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3200 writeln("max = ", context.max());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3201 writeln("max1 = ", Decimal(999999999, 99));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3202 writeln("dig = ", context.dig());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3203 writeln("eps = ", context.epsilon());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3204 writeln("smallest = ", context.min_normal()*context.epsilon());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3205 writeln("1/epsilon = ", Decimal(1)/context.epsilon());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3206 writeln("max * min = ", context.max * context.min_normal);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3207 writeln("mant_dig = ", context.mant_dig);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3208 writeln("min_exp = ", context.min_exp);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3209 writeln("max_exp = ", context.max_exp);+/
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3210
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3211
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3212 // TODO: this next one goes crazy -- shows need for checks on construction
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3213 // TODO: turns out this is being converted to a double (or real) and
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3214 // then it's really weird.
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3215 // writeln("bigger = ", Decimal(999999999999));
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3216 // float f = float.max;
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3217 // TODO: convert these to assserts
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3218 /+ writeln("f.max = ", f);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3219 writeln("f.min = ", float.min);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3220 writeln("f = ", 2 * float.min);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3221 writeln("d.max = ", Decimal.max());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3222 writeln("d.min = ", Decimal.min_normal());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3223 writeln("2 * d.min = ", 2 * Decimal.min_normal());
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3224 writeln("0.1 * d.min = ", 0.1 * Decimal.min_normal());+/
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3225 // TODO: move this to unittesting
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3226 /+ Decimal dec = Decimal(PI);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3227 writeln("pi = ", dec );
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3228 dec = Decimal(PI, 19);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3229 writeln("pi = ", dec );
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3230 dec = Decimal(1.3, 25);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3231 writeln("pi = ", dec );
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3232 dec = Decimal(0.1, 25);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3233 writeln("pi = ", dec );
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3234 dec = Decimal(2.0, 25);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3235 writeln("pi = ", dec );
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3236 dec = Decimal(200.5, 25);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3237 writeln("pi = ", dec );
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3238 writeln(double.dig);
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3239 writeln(real.dig);+/
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3240 }
42cf4db6be32 Creation
Paul (paul.d.anderson@comcast.net)
parents:
diff changeset
3241