note description: "User selectable parameters and rules which govern the results of decimal arithmetic operations" library: "Gobo Eiffel Decimal Arithmetic Library" copyright: "Copyright (c) 2004, Paul G. Crismer and others" license: "MIT License" date: "$Date: 2019-02-07 22:54:15 +0000 (Thu, 07 Feb 2019) $" revision: "$Revision: 102807 $" class MA_DECIMAL_CONTEXT inherit ANY redefine out, copy, is_equal end KL_CLONABLE undefine out, copy, is_equal end MA_DECIMAL_CONTEXT_CONSTANTS undefine out, copy, is_equal end KL_SHARED_EXCEPTIONS undefine out, copy, is_equal end KL_IMPORTED_STRING_ROUTINES undefine out, copy, is_equal end KL_IMPORTED_ARRAY_ROUTINES undefine out, copy, is_equal end create make_default, make_double, make_extended, make_double_extended, make feature {NONE} -- Initialization make_default -- Create a new default context for general purpose arithmetic (IEEE 854), single precision. local index: INTEGER_32 do make (Default_digits, Default_rounding_mode) from index := Default_traps.lower until index > Default_traps.upper loop enable_trap (Default_traps.item (index)) index := index + 1 end ensure default_digits: digits = Default_digits default_rounding_mode: rounding_mode = Default_rounding_mode trap_division_by_zero: is_trapped (Signal_division_by_zero) trap_invalid_operation: is_trapped (Signal_invalid_operation) trap_overflow: is_trapped (Signal_overflow) trap_underflow: is_trapped (Signal_underflow) end make_double -- Create a new double precision context. do make_default digits := 2 * Default_digits + 1 ensure default_digits: digits = 2 * Default_digits + 1 default_rounding_mode: rounding_mode = Default_rounding_mode trap_division_by_zero: is_trapped (Signal_division_by_zero) trap_invalid_operation: is_trapped (Signal_invalid_operation) trap_overflow: is_trapped (Signal_overflow) trap_underflow: is_trapped (Signal_underflow) end make_extended -- Create a new extended default context (IEEE 854), single precision. do make (Default_digits, Round_half_even) is_extended := True ensure default_digits: digits = Default_digits default_rounding_mode: rounding_mode = Round_half_even end make_double_extended -- Create a new extented default context, double precision. do make_extended digits := 2 * Default_digits + 1 ensure default_digits: digits = 2 * Default_digits + 1 default_rounding_mode: rounding_mode = Round_half_even end make (a_digits, a_rounding_mode: INTEGER_32) -- Create a new math context. require a_digits_valid: a_digits >= Minimum_digits and a_digits <= Maximum_digits a_rounding_mode_valid: Integer_array_.has (Rounds, a_rounding_mode) do digits := a_digits rounding_mode := a_rounding_mode create traps.make_filled (False, Signal_division_by_zero, Signal_subnormal) create flags.make_filled (False, Signal_division_by_zero, Signal_subnormal) exponent_limit := Maximum_exponent ensure digits_set: digits = a_digits rounding_mode_set: rounding_mode = a_rounding_mode exponent_limit: exponent_limit = Maximum_exponent end feature -- Access digits: INTEGER_32 -- Number of digits (precision) to be used for an operation. -- The DECIMAL operators use this value to determine the precision of results. -- Note that leading zeros (in the integer part of a number) are never significant. precision: INTEGER_32 -- Synonym for 'digits' do Result := digits ensure synonym_of_digits: Result = digits end rounding_mode: INTEGER_32 -- Rounding algorithm to be used for an operation when non-zero digits have to -- be discarded in order to reduce the precision of a result reason: detachable STRING_8 -- Reason of latest raised signal exponent_limit: INTEGER_32 -- Exponent limit; -- Exponents can range from -exponent_limit through +exponent_limit e_tiny: INTEGER_32 -- Minimum value of the exponent for subnormal numbers do Result := (- exponent_limit) - (digits - 1) end feature -- Access Default_context: MA_DECIMAL_CONTEXT obsolete "Use MA_SHARED_DECIMAL_CONTEXT instead. [2005-09-11]" -- Default context for general purpose arithmetic once create Result.make_default ensure default_context_not_void: Result /= Void end feature -- Status report is_flagged (a_signal: INTEGER_32): BOOLEAN -- Is a_signal flagged? require valid_signal: valid_signal (a_signal) do Result := flags.item (a_signal) end is_trapped (a_signal: INTEGER_32): BOOLEAN -- Is a_signal trapped? require valid_signal: valid_signal (a_signal) do Result := traps.item (a_signal) end valid_signal (a_signal: INTEGER_32): BOOLEAN -- Is a_signal a valid one? do Result := Integer_array_.has (Signals, a_signal) end is_extended: BOOLEAN -- Is current context extended? exception_on_trap: BOOLEAN -- Should an exception be raised when trap occurs? feature -- Element change set_digits (some_digits: INTEGER_32) -- Set digits to some_digits. require some_digits_valid: some_digits >= Minimum_digits and some_digits <= Maximum_digits do digits := some_digits ensure digits_set: digits = some_digits end set_exponent_limit (a_limit: INTEGER_32) -- Set exponent_limit to a_limit. require limit_positive: a_limit >= 0 do exponent_limit := a_limit ensure limit_set: exponent_limit = a_limit end enable_exception_on_trap -- Enable exception when trap occurs. do exception_on_trap := True end disable_exception_on_trap -- Disable exception when trap occurs. do exception_on_trap := False end enable_trap (a_signal: INTEGER_32) -- Enable trapping of a_signal. require valid_signal: valid_signal (a_signal) do traps.put (True, a_signal) ensure trapped_signal: is_trapped (a_signal) end disable_trap (a_signal: INTEGER_32) -- Enable trapping of a_signal. require valid_signal: valid_signal (a_signal) do traps.put (False, a_signal) ensure not_trapped_signal: not is_trapped (a_signal) end set_flag (a_signal: INTEGER_32) -- Flag a_signal. require valid_signal: valid_signal (a_signal) do flags.put (True, a_signal) ensure flagged_signal: is_flagged (a_signal) end reset_flag (a_signal: INTEGER_32) -- Reset a_signal. require valid_signal: valid_signal (a_signal) do flags.put (False, a_signal) ensure unflagged_signal: not is_flagged (a_signal) end reset_flags -- Reset all signals to zero. local i, nb: INTEGER_32 do from i := flags.lower nb := flags.upper until i > nb loop flags.put (False, i) i := i + 1 end end set_rounding_mode (a_mode: INTEGER_32) -- Set rounding_mode to a_mode. require valid_mode: Integer_array_.has (Rounds, a_mode) do rounding_mode := a_mode ensure rounding_mode_set: rounding_mode = a_mode end set_extended -- Set is_extended to True. do is_extended := True ensure extended: is_extended end set_normal -- Set is_extended to False. do is_extended := False ensure normal: not is_extended end feature -- Conversion out: STRING_8 -- Printable representation do create Result.make (30) Result.append_string ("digits=") Result.append_string (digits.out) Result.append_string (" rounding_mode=") Result.append_string (Round_words.item (Round_words.lower + rounding_mode)) end feature -- Comparison is_equal (other: like Current): BOOLEAN -- Is other equal to Current? do Result := digits = other.digits Result := Result and then exception_on_trap = other.exception_on_trap Result := Result and then exponent_limit = other.exponent_limit Result := Result and then flags.is_equal (other.flags) Result := Result and then is_extended = other.is_extended Result := Result and then rounding_mode = other.rounding_mode Result := Result and then traps.is_equal (other.traps) end feature -- Basic operations signal (a_signal: INTEGER_32; a_message: STRING_8) -- Raise flag a_signal for a_message reason. require valid_signal: valid_signal (a_signal) a_message_not_void: a_message /= Void local exception_message: STRING_8 do set_flag (a_signal) reason := a_message if is_trapped (a_signal) and then exception_on_trap then exception_message := String_.cloned_string (Signal_words.item (a_signal)) exception_message.append_string (" : ") exception_message.append_string (a_message) Exceptions.raise (exception_message) end ensure flagged_signal: is_flagged (a_signal) reason_set: reason = a_message end feature -- Duplication copy (other: like Current) -- Copy other. do standard_copy (other) flags := Boolean_array_.cloned_array (other.flags) traps := Boolean_array_.cloned_array (other.traps) end feature {MA_DECIMAL_HANDLER, MA_DECIMAL_CONTEXT} -- Signals flags: ARRAY [BOOLEAN] -- Signals flagged traps: ARRAY [BOOLEAN] -- Signals trapped feature {MA_DECIMAL} -- Implementation force_digits (d: INTEGER_32) -- Force digits to d, just for do_underflow. require d_positive: d >= 0 do digits := d ensure digits_set: digits = d end invariant positive_digits: digits >= 0 rounding_mode_valid: rounding_mode = Round_ceiling or rounding_mode = Round_down or rounding_mode = Round_floor or rounding_mode = Round_half_down or rounding_mode = Round_half_even or rounding_mode = Round_half_up or rounding_mode = Round_unnecessary or rounding_mode = Round_up flags_not_void: flags /= Void flags_lower: flags.lower = Signal_division_by_zero flags_upper: flags.upper = Signal_subnormal traps_not_void: traps /= Void traps_lower: traps.lower = Signal_division_by_zero traps_upper: traps.upper = Signal_subnormal end -- class MA_DECIMAL_CONTEXT
Generated by ISE EiffelStudio