note description: "[ An arbitrary precision library for decimal numbers. Following the 'General Decimal Arithmetic Specification' of gobo MA_DECIMAL. Creation make_from_string make_from_decimal make_from_int make_from_big_int make_from_rational Queries as_big_int: BIG_INTEGER as_rational: RATIONAL as_real32: REAL_32 as_real64: REAL_64 exp alias "^" (power: DECIMAL): DECIMAL identity alias "+": DECIMAL is_equal (other: DECIMAL): BOOLEAN is_greater alias ">" (other: DECIMAL): BOOLEAN is_greater_equal alias ">=" (other: DECIMAL): BOOLEAN is_integer: BOOLEAN is_less alias "<" (other: DECIMAL): BOOLEAN is_less_equal alias "<=" (other: DECIMAL): BOOLEAN is_natural: BOOLEAN is_natural1: BOOLEAN is_negative: BOOLEAN is_real32: BOOLEAN is_real64: BOOLEAN max (other: DECIMAL): DECIMAL min (other: DECIMAL): DECIMAL minus alias "-" (other: DECIMAL): DECIMAL one: DECIMAL opposite alias "-": DECIMAL out: STRING plus alias "+" (other: DECIMAL): DECIMAL precise_out: STRING precise_out_to (digits: INTEGER): STRING product alias "*" (other: DECIMAL): DECIMAL quotient alias "/" (other: DECIMAL): DECIMAL sqrt: DECIMAL round_to (digits: INTEGER): DECIMAL zero: DECIMAL Commands round (digits: INTEGER) set_precision (precision: INTEGER) ]" author: "JSO, DC, and CD" date: "$Date$" revision: "$Revision$" class interface DECIMAL create make_from_string (s: STRING_8) -- create an object from string 's' require non_void: s /= Void non_empty: not s.is_empty has_correct_format: ensurevalid (s) make_from_decimal (decimal: MA_DECIMAL) -- create DECIMAL_WRAPPER from MA_DECIMAL make_from_int (int: INTEGER_32) -- create a DECIMAL object from integer m default_create -- create an empty object (it's equivalent to 0) require -- from ANY True ensure then item.is_equal ("0") make_from_string_ctx (value_string: STRING_8; ctx: MA_DECIMAL_CONTEXT) -- Make a new decimal from value_string relative to ctx make_with_precision (a_value: STRING_8; a_precision: INTEGER_32) -- Make a new decimal from a_value with `a_precision require positive_precision: a_precision > 0 make_from_big_int (big_int: BIG_INTEGER) -- Create from BIG_INTEGER make_from_rational (rational: RATIONAL) -- Create from RATIONAL convert make_from_rational ({STRING_8}), make_from_rational ({BIG_INTEGER}), make_from_rational ({RATIONAL}), make_from_rational: {REAL_64}, make_from_rational: {BIG_INTEGER}, make_from_rational: {RATIONAL}, make_from_rational: {STRING_8} feature -- Access generating_type: TYPE [detachable DECIMAL] -- Type of current object -- (type of which it is a direct instance) -- (from ANY) ensure -- from ANY generating_type_not_void: Result /= Void generator: STRING_8 -- Name of current object's generating class -- (base class of the type of which it is a direct instance) -- (from ANY) ensure -- from ANY generator_not_void: Result /= Void generator_not_empty: not Result.is_empty feature -- Comparison frozen deep_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void -- or attached to isomorphic object structures? -- (from ANY) ensure -- from ANY instance_free: class shallow_implies_deep: standard_equal (a, b) implies Result both_or_none_void: (a = Void) implies (Result = (b = Void)) same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b)) symmetric: Result implies deep_equal (b, a) frozen equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached -- to objects considered equal? -- (from ANY) ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.is_equal (b)) frozen is_deep_equal (other: DECIMAL): BOOLEAN -- Are Current and other attached to isomorphic object structures? -- (from ANY) require -- from ANY other_not_void: other /= Void ensure -- from ANY shallow_implies_deep: standard_is_equal (other) implies Result same_type: Result implies same_type (other) symmetric: Result implies other.is_deep_equal (Current) is_greater alias ">" (other: DECIMAL): BOOLEAN -- Is current object greater than other? -- (from COMPARABLE) require -- from PART_COMPARABLE other_exists: other /= Void ensure then -- from COMPARABLE definition: Result = (other < Current) is_greater_equal alias ">=" (other: DECIMAL): BOOLEAN -- Is current object greater than or equal to other? -- (from COMPARABLE) require -- from PART_COMPARABLE other_exists: other /= Void ensure then -- from COMPARABLE definition: Result = (other <= Current) is_less_equal alias "<=" (other: DECIMAL): BOOLEAN -- Is current object less than or equal to other? -- (from COMPARABLE) require -- from PART_COMPARABLE other_exists: other /= Void ensure then -- from COMPARABLE definition: Result = ((Current < other) or (Current ~ other)) max (other: DECIMAL): DECIMAL -- The greater of current object and other -- (from COMPARABLE) require -- from COMPARABLE other_exists: other /= Void ensure -- from COMPARABLE current_if_not_smaller: Current >= other implies Result = Current other_if_smaller: Current < other implies Result = other min (other: DECIMAL): DECIMAL -- The smaller of current object and other -- (from COMPARABLE) require -- from COMPARABLE other_exists: other /= Void ensure -- from COMPARABLE current_if_not_greater: Current <= other implies Result = Current other_if_greater: Current > other implies Result = other frozen standard_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached to -- field-by-field identical objects of the same type? -- Always uses default object comparison criterion. -- (from ANY) ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.standard_is_equal (b)) frozen standard_is_equal (other: DECIMAL): BOOLEAN -- Is other attached to an object of the same type -- as current object, and field-by-field identical to it? -- (from ANY) require -- from ANY other_not_void: other /= Void ensure -- from ANY same_type: Result implies same_type (other) symmetric: Result implies other.standard_is_equal (Current) three_way_comparison (other: DECIMAL): INTEGER_32 -- If current object equal to other, 0; -- if smaller, -1; if greater, 1 -- (from COMPARABLE) require -- from COMPARABLE other_exists: other /= Void ensure -- from COMPARABLE equal_zero: (Result = 0) = (Current ~ other) smaller_negative: (Result = -1) = (Current < other) greater_positive: (Result = 1) = (Current > other) feature -- Status report conforms_to (other: ANY): BOOLEAN -- Does type of current object conform to type -- of other (as per Eiffel: The Language, chapter 13)? -- (from ANY) require -- from ANY other_not_void: other /= Void same_type (other: ANY): BOOLEAN -- Is type of current object identical to type of other? -- (from ANY) require -- from ANY other_not_void: other /= Void ensure -- from ANY definition: Result = (conforms_to (other) and other.conforms_to (Current)) feature -- Duplication copy (other: DECIMAL) -- Update current object using fields of object attached -- to other, so as to yield equal objects. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) ensure -- from ANY is_equal: Current ~ other frozen deep_copy (other: DECIMAL) -- Effect equivalent to that of: -- copy (other . deep_twin) -- (from ANY) require -- from ANY other_not_void: other /= Void ensure -- from ANY deep_equal: deep_equal (Current, other) frozen deep_twin: DECIMAL -- New object structure recursively duplicated from Current. -- (from ANY) ensure -- from ANY deep_twin_not_void: Result /= Void deep_equal: deep_equal (Current, Result) frozen standard_copy (other: DECIMAL) -- Copy every field of other onto corresponding field -- of current object. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) ensure -- from ANY is_standard_equal: standard_is_equal (other) frozen standard_twin: DECIMAL -- New object field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) ensure -- from ANY standard_twin_not_void: Result /= Void equal: standard_equal (Result, Current) frozen twin: DECIMAL -- New object equal to Current -- twin calls copy; to change copying/twinning semantics, redefine copy. -- (from ANY) ensure -- from ANY twin_not_void: Result /= Void is_equal: Result ~ Current feature -- Basic operations frozen default: detachable DECIMAL -- Default value of object's type -- (from ANY) frozen default_pointer: POINTER -- Default value of type POINTER -- (Avoid the need to write p.default for -- some p of type POINTER.) -- (from ANY) ensure -- from ANY instance_free: class default_rescue -- Process exception for routines with no Rescue clause. -- (Default: do nothing.) -- (from ANY) frozen do_nothing -- Execute a null action. -- (from ANY) ensure -- from ANY instance_free: class feature -- Output Io: STD_FILES -- Handle to standard file setup -- (from ANY) ensure -- from ANY instance_free: class io_not_void: Result /= Void print (o: detachable ANY) -- Write terse external representation of o -- on standard output. -- (from ANY) ensure -- from ANY instance_free: class frozen tagged_out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) ensure -- from ANY tagged_out_not_void: Result /= Void feature -- Platform Operating_environment: OPERATING_ENVIRONMENT -- Objects available from the operating system -- (from ANY) ensure -- from ANY instance_free: class operating_environment_not_void: Result /= Void feature -- comparison is_equal (other: DECIMAL): BOOLEAN -- check whether other is equal to current or not require -- from ANY other_not_void: other /= Void ensure -- from ANY symmetric: Result implies other ~ Current consistent: standard_is_equal (other) implies Result ensure then -- from COMPARABLE trichotomy: Result = (not (Current < other) and not (other < Current)) is_less alias "<" (other: DECIMAL): BOOLEAN -- whether current is less than other require -- from PART_COMPARABLE other_exists: other /= Void ensure then -- from COMPARABLE asymmetric: Result implies not (other < Current) feature -- conversion as_big_int: BIG_INTEGER -- Represent as BIG_INTEGER require is_integer: is_integer as_rational: RATIONAL -- Represent as RATIONAL as_real32: REAL_32 -- represent as a REAL_32 require valid_real32: is_real32 as_real64: REAL_64 -- represent as a REAL_64 require valid_real64: is_real64 feature -- operations absolute: DECIMAL -- returns the absoulte value of Current add (other: DECIMAL): DECIMAL -- adds current to other and returns a new object -- The new DECIMAL will have a precision based on the criteria in calculate_new_precision -- Was declared in DECIMAL as synonym of plus. ceiling: DECIMAL -- Returns the smallest integer greater than or equal to Current divide (other: DECIMAL): DECIMAL -- divides current by other and returns a new object -- The new DECIMAL will have a precision based on the criteria in calculate_new_precision -- Was declared in DECIMAL as synonym of quotient. require other_non_zero: other /~ zero exp alias "^" (p: DECIMAL): DECIMAL -- calculates the value of current instance raised to 'power' (capped to 500 digits of precision) -- Was declared in DECIMAL as synonym of exponent and power. require is_exponentiable: exponentiable (p) exponent (p: DECIMAL): DECIMAL -- calculates the value of current instance raised to 'power' (capped to 500 digits of precision) -- Was declared in DECIMAL as synonym of exp and power. require is_exponentiable: exponentiable (p) floor: DECIMAL -- Returns the greatest integer less than or equal to Current minus alias "-" (other: DECIMAL): DECIMAL -- subtracts other from current and returns a new object -- The new DECIMAL will have a precision based on the criteria in calculate_new_precision -- Was declared in DECIMAL as synonym of subtract. multiply (other: DECIMAL): DECIMAL -- multiplies current by other and returns a new object -- The new DECIMAL will have a precision based on the criteria in calculate_new_precision -- Was declared in DECIMAL as synonym of product. negate -- negates Current plus alias "+" (other: DECIMAL): DECIMAL -- adds current to other and returns a new object -- The new DECIMAL will have a precision based on the criteria in calculate_new_precision -- Was declared in DECIMAL as synonym of add. power (p: DECIMAL): DECIMAL -- calculates the value of current instance raised to 'power' (capped to 500 digits of precision) -- Was declared in DECIMAL as synonym of exp and exponent. require is_exponentiable: exponentiable (p) product alias "*" (other: DECIMAL): DECIMAL -- multiplies current by other and returns a new object -- The new DECIMAL will have a precision based on the criteria in calculate_new_precision -- Was declared in DECIMAL as synonym of multiply. quotient alias "/" (other: DECIMAL): DECIMAL -- divides current by other and returns a new object -- The new DECIMAL will have a precision based on the criteria in calculate_new_precision -- Was declared in DECIMAL as synonym of divide. require other_non_zero: other /~ zero sqrt: DECIMAL -- calculates square root for this instance require non_negative: not is_negative subtract (other: DECIMAL): DECIMAL -- subtracts other from current and returns a new object -- The new DECIMAL will have a precision based on the criteria in calculate_new_precision -- Was declared in DECIMAL as synonym of minus. feature -- queries debug_output: STRING_8 -- String that should be displayed in debugger to represent Current. ensure -- from DEBUG_OUTPUT result_not_void: Result /= Void divisible (other: DECIMAL): BOOLEAN -- may current object be divided by other? exponentiable (other: DECIMAL): BOOLEAN -- may current object be elevated to the power other? identity alias "+": DECIMAL -- unary plus is_integer: BOOLEAN -- Is Current an integer number? is_natural: BOOLEAN -- Is Current an Natural number? is_natural1: BOOLEAN -- Is Current an Natural1 number? is_negative: BOOLEAN -- Is Current less than or equal to zero? is_real32: BOOLEAN is_real64: BOOLEAN -- Is Current a double? one: DECIMAL -- neutral element for "*" and "/" opposite alias "-": DECIMAL -- unary minus out: STRING_8 -- return a representation of the number rounded to two decimal places ensure -- from ANY out_not_void: Result /= Void precise_out: STRING_8 -- return precise representation of the number zero: DECIMAL -- neutral element for "+" and "-" feature -- rounding get_precision: INTEGER_32 -- returns the current number of digits being kept by the number precise_out_to (digits: INTEGER_32): STRING_8 -- returns the precise string representation to rounded to the specified 'digits' number of decimal places require positive_digits: digits >= 0 reset_precision -- resets the precision of Current for future operations to Default_precision round (digits: INTEGER_32) -- rounds this instance to the specified digits number of decimal places require positive_digits: digits >= 0 round_to (digits: INTEGER_32): DECIMAL -- Returns a decimal that is the current value rounded to the specified 'digits' number of decimal places -- Uses default strategy as set in ma_decimal_ctx (half up) require positive_digits: digits >= 0 set_precision (precision: INTEGER_32) -- sets the precision of Current for future operations require precision_positive: precision > 0 invariant consistent_rounding: Default_rounding = {MA_DECIMAL_CONTEXT}.round_half_up -- from COMPARABLE irreflexive_comparison: not (Current < Current) -- from ANY reflexive_equality: standard_is_equal (Current) reflexive_conformance: conforms_to (Current) note info: "[ For an oracle see http://delaneyrm.com/MPCalcRB.html. test: BOOLEAN local d1, d2, d3, d4, d5, d6: DECIMAL r64: REAL_64 i: INTEGER r: RATIONAL do comment ("test: Mortgage Calculation in REAL_64 vs DECIMAL") -- floating point arithmetic cannot distinguish -- between 0.4 and 0.40000000000000002 r64 := 0.1 + 0.3 Result := r64 = 0.4 and r64 = 0.40000000000000002 check Result end -- decimal arithmetic can d1 := "0.1" ; d2 := "0.3" d3 := d1 + d2 Result := d3 ~ "0.4"and d3 /~ "0.40000000000000002" check Result end assert_equal ("precise_out test", "0.4", d3.precise_out) assert_equal ("out test1", "0.40", d3.out) r64 := 100000*(1+0.05/12)^360 Result := r64 = 446774.43140061089 check Result end d1 := "100000" d2 := "0.05"; d3 := "12"; d4 := "360" d2.set_precision(120) d5 := d1 * (d1.one + d2/d3)^d4 Result := d5.precise_out.starts_with ("446774.431400613221242807011041301589597772674487270698002439224547330881614835011308578390042190134313238565062087470576") check Result end assert_equal ("out test2", "446774.43", d5.out) d6 := d5 - "446774.43140061089" Result := d6.precise_out.starts_with ("0.000000002331242807011041301589597772674487270698002439224547330881614835011308578390042190134313238565062087470576") check Result end end ]" end -- class DECIMAL
Generated by ISE EiffelStudio