lib/flt/support.rb in flt-1.3.3 vs lib/flt/support.rb in flt-1.3.4

- old
+ new

@@ -355,10 +355,55 @@ round_mode = :down end round_mode end + # Adjust truncated digits based on the rounding mode (:round_mode option) + # and on the information about the following digits contained in the :round_up + # parameter (nil for only zeros, :lo for nonzero values below tie, :tie for a :tie + # and :hi for nonzero digits over the tie). Other parameters: :negative to consider + # the number negative, :base the base of the number. + def adjust_digits(dec_pos, digits, options={}) + round_mode = options[:round_mode] + negative = options[:negative] + round_up = options[:round_up] + base = options[:base] + round_mode = simplified_round_mode(round_mode, negative) + + increment = (round_up && (round_mode != :down)) && + ((round_mode == :up) || + (round_up == :hi) || + ((round_up == :tie) && + ((round_mode==:half_up) || + ((round_mode==:half_even) && ((digits.last % 2)==1))))) + + if increment + digits = digits.dup + # carry = increment ? 1 : 0 + # digits = digits.reverse.map{|d| d += carry; d>=base ? 0 : (carry=0;d)}.reverse + # if carry != 0 + # digits.unshift carry + # dec_pos += 1 + # end + i = digits.size - 1 + while i>=0 + digits[i] += 1 + if digits[i] == base + digits[i] = 0 + else + break + end + i -= 1 + end + if i<0 + dec_pos += 1 + digits.unshift 1 + end + end + [dec_pos, digits] + end + # Floating-point reading and printing (from/to text literals). # # Here are methods for floating-point reading, using algorithms by William D. Clinger, and # printing, using algorithms by Robert G. Burger and R. Kent Dybvig. # @@ -1007,50 +1052,17 @@ return @k, @digits end attr_reader :round_up, :repeat - # Access rounded result of format operation: scaling (position of radix point) and digits def adjusted_digits(round_mode) - round_mode = Support.simplified_round_mode(round_mode, @minus) if @adjusted_digits.nil? && !@digits.nil? - increment = (@round_up && (round_mode != :down)) && - ((round_mode == :up) || - (@round_up == :hi) || - ((@round_up == :tie) && - ((round_mode==:half_up) || ((round_mode==:half_even) && ((@digits.last % 2)==1))))) - # increment = (@round_up == :tie) || (@round_up == :hi) # old behaviour (:half_up) - if increment - base = @output_b - dec_pos = @k - digits = @digits.dup - # carry = increment ? 1 : 0 - # digits = digits.reverse.map{|d| d += carry; d>=base ? 0 : (carry=0;d)}.reverse - # if carry != 0 - # digits.unshift carry - # dec_pos += 1 - # end - i = digits.size - 1 - while i>=0 - digits[i] += 1 - if digits[i] == base - digits[i] = 0 - else - break - end - i -= 1 - end - if i<0 - dec_pos += 1 - digits.unshift 1 - end - @adjusted_k = dec_pos - @adjusted_digits = digits - else - @adjusted_k = @k - @adjusted_digits = @digits - end + @adjusted_k, @adjusted_digits = Support.adjust_digits(@k, @digits, + :round_mode => round_mode, + :negative => @minus, + :round_up => @round_up, + :base => @output_b) end return @adjusted_k, @adjusted_digits end # Given r/s = v (number to convert to text), m_m/s = (v - v-)/s, m_p/s = (v+ - v)/s