comparison src/decimal/context.d @ 0:42cf4db6be32

Creation
author Paul (paul.d.anderson@comcast.net)
date Sat, 13 Mar 2010 13:22:25 -0800
parents
children abf9d7974708
comparison
equal deleted inserted replaced
-1:000000000000 0:42cf4db6be32
1 module decimal.context;
2
3 import decimal.decimal;
4 import std.string;
5
6 //--------------------------
7 //
8 // DecimalContext struct
9 //
10 //--------------------------
11
12 /**
13 * Enumeration of available rounding modes.
14 */
15 public enum Rounding {
16 HALF_EVEN,
17 HALF_DOWN,
18 HALF_UP,
19 DOWN,
20 UP,
21 FLOOR,
22 CEILING,
23 }
24
25
26 // context flags
27 public enum : ubyte {
28 CLAMPED = 0x01,
29 DIVISION_BY_ZERO = 0x02,
30 INEXACT = 0x04,
31 INVALID_OPERATION = 0x08,
32 OVERFLOW = 0x10,
33 ROUNDED = 0x20,
34 SUBNORMAL = 0x40,
35 UNDERFLOW = 0x80
36 }
37
38 /+public:
39 static immutable ubyte CLAMPED = 0x01;
40 static immutable ubyte DIVISION_BY_ZERO = 0x02;
41 static immutable ubyte INEXACT = 0x04;
42 static immutable ubyte INVALID_OPERATION = 0x08;
43 static immutable ubyte OVERFLOW = 0x10;
44 static immutable ubyte ROUNDED = 0x20;
45 static immutable ubyte SUBNORMAL = 0x40;
46 static immutable ubyte UNDERFLOW = 0x80;+/
47
48 /**
49 * Context for Decimal mathematic operations
50 */
51 public struct DecimalContext {
52 public:
53 Rounding mode = Rounding.HALF_EVEN;
54 uint precision = 9;
55 ubyte traps;
56 ubyte flags;
57 int eMin = -98;
58 int eMax = 99;
59
60 const int eTiny() {
61 return eMin - (precision - 1);
62 }
63
64 /// Returns the number of decimal digits in this context.
65 const uint dig() {
66 return precision;
67 }
68
69 /// returns the smallest available increment to one in this context
70 const Decimal epsilon() {
71 return Decimal(1,-precision);
72 }
73
74 /// Returns the number of binary digits in this context.
75 const int mant_dig() {
76 return cast(int)(precision/LOG2);
77 }
78
79 const int min_exp() {
80 return cast(int)(eMin/LOG2);
81 }
82
83 const int max_exp() {
84 return cast(int)(eMax/LOG2);
85 }
86
87 const int min_10_exp() {
88 return eMin;
89 }
90
91 const int max_10_exp() {
92 return eMax;
93 }
94
95 /// Returns the maximum representable normal value in the current context.
96 // TODO: Replace this formula with a single execution when precision or eMax is changed.
97 const Decimal max() {
98 string cstr = "9." ~ repeat("9", precision-1) ~ "E" ~ format("%d", eMax);
99 return Decimal(cstr);
100 }
101
102 // Returns the minimum representable normal value in the current context.
103 const Decimal min_normal() {
104 return Decimal(1, eMin);
105 }
106
107 // Returns the minimum representable subnormal value in the current context.
108 const Decimal min() {
109 return Decimal(1, eTiny);
110 }
111
112 /+ public const int getPrecision() {
113 return precision;
114 }
115
116 public void setPrecision(int precision) {
117 this.precision = precision;
118 }+/
119
120 const void setFlag(const ubyte flag, const bool value = true) {
121 if (value) {
122 context.flags |= flag;
123 }
124 else {
125 context.flags &= !flag;
126 }
127 }
128
129 public bool getFlag(const ubyte flag) {
130 return (context.flags & flag) == flag;
131 }
132
133 public void clearFlags() {
134 context.flags = 0;
135 }
136
137
138 }; // end struct DecimalContext
139
140 public:
141 // default context
142 immutable DecimalContext DEFAULT_CONTEXT = DecimalContext();
143
144 private:
145 // context stack
146 struct ContextStack {
147 private:
148 DecimalContext[] stack = [ DEFAULT_CONTEXT ];
149 uint capacity = 1;
150 uint count = 1;
151
152 public void push() {
153 if (count >= capacity) {
154 capacity *= 2;
155 stack.length = capacity;
156 }
157 count++;
158 stack[count-1] = context;
159 }
160
161 public void pop() {
162 if (count == 0) {
163 push();
164 }
165 if (count == 1) {
166 context = stack[0];
167 }
168 else {
169 count--;
170 context = stack[count-1];
171 }
172 }
173
174 } // end struct ContextStack
175
176 //--------------------------
177 //
178 // Emd of DecimalContext struct
179 //
180 //--------------------------
181
182