Mercurial > projects > decimal
view 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 |
line wrap: on
line source
module decimal.context; import decimal.decimal; import std.string; //-------------------------- // // DecimalContext struct // //-------------------------- /** * Enumeration of available rounding modes. */ public enum Rounding { HALF_EVEN, HALF_DOWN, HALF_UP, DOWN, UP, FLOOR, CEILING, } // context flags public enum : ubyte { CLAMPED = 0x01, DIVISION_BY_ZERO = 0x02, INEXACT = 0x04, INVALID_OPERATION = 0x08, OVERFLOW = 0x10, ROUNDED = 0x20, SUBNORMAL = 0x40, UNDERFLOW = 0x80 } /+public: static immutable ubyte CLAMPED = 0x01; static immutable ubyte DIVISION_BY_ZERO = 0x02; static immutable ubyte INEXACT = 0x04; static immutable ubyte INVALID_OPERATION = 0x08; static immutable ubyte OVERFLOW = 0x10; static immutable ubyte ROUNDED = 0x20; static immutable ubyte SUBNORMAL = 0x40; static immutable ubyte UNDERFLOW = 0x80;+/ /** * Context for Decimal mathematic operations */ public struct DecimalContext { public: Rounding mode = Rounding.HALF_EVEN; uint precision = 9; ubyte traps; ubyte flags; int eMin = -98; int eMax = 99; const int eTiny() { return eMin - (precision - 1); } /// Returns the number of decimal digits in this context. const uint dig() { return precision; } /// returns the smallest available increment to one in this context const Decimal epsilon() { return Decimal(1,-precision); } /// Returns the number of binary digits in this context. const int mant_dig() { return cast(int)(precision/LOG2); } const int min_exp() { return cast(int)(eMin/LOG2); } const int max_exp() { return cast(int)(eMax/LOG2); } const int min_10_exp() { return eMin; } const int max_10_exp() { return eMax; } /// Returns the maximum representable normal value in the current context. // TODO: Replace this formula with a single execution when precision or eMax is changed. const Decimal max() { string cstr = "9." ~ repeat("9", precision-1) ~ "E" ~ format("%d", eMax); return Decimal(cstr); } // Returns the minimum representable normal value in the current context. const Decimal min_normal() { return Decimal(1, eMin); } // Returns the minimum representable subnormal value in the current context. const Decimal min() { return Decimal(1, eTiny); } /+ public const int getPrecision() { return precision; } public void setPrecision(int precision) { this.precision = precision; }+/ const void setFlag(const ubyte flag, const bool value = true) { if (value) { context.flags |= flag; } else { context.flags &= !flag; } } public bool getFlag(const ubyte flag) { return (context.flags & flag) == flag; } public void clearFlags() { context.flags = 0; } }; // end struct DecimalContext public: // default context immutable DecimalContext DEFAULT_CONTEXT = DecimalContext(); private: // context stack struct ContextStack { private: DecimalContext[] stack = [ DEFAULT_CONTEXT ]; uint capacity = 1; uint count = 1; public void push() { if (count >= capacity) { capacity *= 2; stack.length = capacity; } count++; stack[count-1] = context; } public void pop() { if (count == 0) { push(); } if (count == 1) { context = stack[0]; } else { count--; context = stack[count-1]; } } } // end struct ContextStack //-------------------------- // // Emd of DecimalContext struct // //--------------------------