flt 1.3.2 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.txt +5 -0
- data/README.rdoc +1 -0
- data/lib/flt/support.rb +112 -30
- data/lib/flt/version.rb +1 -1
- data/test/test_formatter.rb +197 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a623d39842de7043c3004b02fe86bf20b4fb6491
|
4
|
+
data.tar.gz: a21afce102fa26145f8f24b8661d6b9bfddb2ae4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bfe19f6b32df81f96b39d1b58b8845c402c66fc3f20b0e4e6cbc45cc4593f1d5e3d37aea6c0f3cbf02a15ef30aae75805ffefb740099fd41bc729f99f0de9bf3
|
7
|
+
data.tar.gz: e4077b0fdcd3ecd337af25b8fec87c47cde43003b89dff3c8621fe4f434589a0f73a726aa32389e40251b47c714db07f94d6845de62bc550cdc9f441a85d1321
|
data/History.txt
CHANGED
data/README.rdoc
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
= Introduction
|
2
2
|
{<img src="https://badge.fury.io/rb/flt.svg" alt="Gem Version" />}[http://badge.fury.io/rb/flt]
|
3
|
+
{<img src="https://travis-ci.org/jgoizueta/flt.svg?branch=master" alt="Build tests" />}[https://travis-ci.org/jgoizueta/flt]
|
3
4
|
|
4
5
|
This library provides arbitrary precision floating-point types for Ruby. All types and
|
5
6
|
functions are within a namespace called Flt. Decimal and Binary floating point numbers
|
data/lib/flt/support.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
module Flt
|
2
2
|
module Support
|
3
|
+
|
4
|
+
class InfiniteLoopError < StandardError
|
5
|
+
end
|
6
|
+
|
3
7
|
# This class assigns bit-values to a set of symbols
|
4
8
|
# so they can be used as flags and stored as an integer.
|
5
9
|
# fv = FlagValues.new(:flag1, :flag2, :flag3)
|
@@ -353,23 +357,22 @@ module Flt
|
|
353
357
|
round_mode
|
354
358
|
end
|
355
359
|
|
356
|
-
|
357
360
|
# Floating-point reading and printing (from/to text literals).
|
358
361
|
#
|
359
|
-
# Here are methods for floating-point reading using algorithms by William D. Clinger and
|
360
|
-
# printing using algorithms by Robert G. Burger and R. Kent Dybvig.
|
362
|
+
# Here are methods for floating-point reading, using algorithms by William D. Clinger, and
|
363
|
+
# printing, using algorithms by Robert G. Burger and R. Kent Dybvig.
|
361
364
|
#
|
362
|
-
# Reading and printing can also viewed as floating-point conversion
|
363
|
-
# floating-point format (the floating-point numbers) and and a free floating-point format (text)
|
364
|
-
# may use different numerical bases.
|
365
|
+
# Reading and printing can also viewed as floating-point conversion between a fixed-precision
|
366
|
+
# floating-point format (the floating-point numbers) and and a free floating-point format (text),
|
367
|
+
# which may use different numerical bases.
|
365
368
|
#
|
366
|
-
# The Reader class
|
369
|
+
# The Reader class, in the default :free mode, converts a free-form numeric value
|
367
370
|
# (as a text literal, i.e. a free floating-point format, usually in base 10) which is taken
|
368
371
|
# as an exact value, to a correctly-rounded floating-point of specified precision and with a
|
369
372
|
# specified rounding mode. It also has a :fixed mode that uses the Formatter class indirectly.
|
370
373
|
#
|
371
374
|
# The Formatter class implements the Burger-Dybvig printing algorithm which converts a
|
372
|
-
# fixed-precision floating point value and produces a text literal in
|
375
|
+
# fixed-precision floating point value and produces a text literal in some base, usually 10,
|
373
376
|
# (equivalently, it produces a floating-point free-format value) so that it rounds back to
|
374
377
|
# the original value (with some specified rounding-mode or any round-to-nearest mode) and with
|
375
378
|
# the same original precision (e.g. using the Clinger algorithm)
|
@@ -822,14 +825,27 @@ module Flt
|
|
822
825
|
# p is the input floating point precision
|
823
826
|
class Formatter
|
824
827
|
|
825
|
-
# This Object-oriented implementation is slower than the functional one for two reasons:
|
828
|
+
# This Object-oriented implementation is slower than the original functional one for two reasons:
|
826
829
|
# * The overhead of object creation
|
827
830
|
# * The use of instance variables instead of local variables
|
828
831
|
# But if scale is optimized or local variables are used in the inner loops, then this implementation
|
829
832
|
# is on par with the functional one for Float and it is more efficient for Flt types, where the variables
|
830
833
|
# passed as parameters hold larger objects.
|
831
834
|
|
832
|
-
|
835
|
+
# A Formatted object is created to format floating point numbers given:
|
836
|
+
# * The input base in which numbers to be formatted are defined
|
837
|
+
# * The input minimum expeonent
|
838
|
+
# * The output base to which the input is converted.
|
839
|
+
# * The :raise_on_repeat option, true by default specifies that when
|
840
|
+
# an infinite sequence of repeating significant digits is found on the output
|
841
|
+
# (which may occur when using the all-digits options and using directed-rounding)
|
842
|
+
# an InfiniteLoopError exception is raised. If this option is false, then
|
843
|
+
# no exception occurs, and instead of generating an infinite sequence of digits,
|
844
|
+
# the formatter object will have a 'repeat' property which designs the first digit
|
845
|
+
# to be repeated (it is an index into digits). If this equals the size of digits,
|
846
|
+
# it is assumend, that the digit to be repeated is a zero which follows the last
|
847
|
+
# digit present in digits.
|
848
|
+
def initialize(input_b, input_min_e, output_b, options={})
|
833
849
|
@b = input_b
|
834
850
|
@min_e = input_min_e
|
835
851
|
@output_b = output_b
|
@@ -844,35 +860,49 @@ module Flt
|
|
844
860
|
# for round-to-nearest it is atie.
|
845
861
|
# * it is :hi otherwise (the value should be rounded-up except for the :down mode)
|
846
862
|
@round_up = nil
|
863
|
+
|
864
|
+
options = { raise_on_repeat: true }.merge(options)
|
865
|
+
# when significant repeating digits occur (+all+ parameter and directed rounding)
|
866
|
+
# @repeat is set to the index of the first repeating digit in @digits;
|
867
|
+
# (if equal to @digits.size, that would indicate an infinite sequence of significant zeros)
|
868
|
+
@repeat = nil
|
869
|
+
# the :raise_on_repeat options (by default true) causes exceptions when repeating is found
|
870
|
+
@raise_on_repeat = options[:raise_on_repeat]
|
847
871
|
end
|
848
872
|
|
849
|
-
# This method converts v = f*b**e into a sequence of output_b
|
873
|
+
# This method converts v = f*b**e into a sequence of +output_b+-base digits,
|
850
874
|
# so that if the digits are converted back to a floating-point value
|
851
|
-
# of precision p (correctly rounded), the result is v.
|
852
|
-
#
|
875
|
+
# of precision p (correctly rounded), the result is exactly v.
|
876
|
+
#
|
877
|
+
# If +round_mode+ is not nil, then just enough digits to produce v using
|
853
878
|
# that rounding is used; otherwise enough digits to produce v with
|
854
879
|
# any rounding are delivered.
|
855
880
|
#
|
856
881
|
# If the +all+ parameter is true, all significant digits are generated without rounding,
|
857
|
-
#
|
882
|
+
# Significant digits here are all digits that, if used on input, cannot arbitrarily change
|
858
883
|
# while preserving the parsed value of the floating point number. Since the digits are not rounded
|
859
884
|
# more digits may be needed to assure round-trip value preservation.
|
885
|
+
#
|
860
886
|
# This is useful to reflect the precision of the floating point value in the output; in particular
|
861
887
|
# trailing significant zeros are shown. But note that, for directed rounding and base conversion
|
862
|
-
# this may need to produce an infinite number of digits, in which case an exception will be raised
|
863
|
-
#
|
864
|
-
#
|
865
|
-
#
|
888
|
+
# this may need to produce an infinite number of digits, in which case an exception will be raised
|
889
|
+
# unless the :raise_on_repeat option has been set to false in the Formatter object. In that case
|
890
|
+
# the formatter objetct will have a +repeat+ property that specifies the point in the digit
|
891
|
+
# sequence where irepetition starts. The digits from that point to the end to the digits sequence
|
892
|
+
# repeat indefinitely.
|
893
|
+
#
|
894
|
+
# This digit-repetition is specially frequent for the :up rounding mode, in which any number
|
895
|
+
# with a finite numberof nonzero digits equal to or less than the precision will haver and infinite
|
896
|
+
# sequence of zero significant digits.
|
866
897
|
#
|
867
|
-
#
|
868
|
-
# point but beware:
|
869
|
-
#
|
870
|
-
# formatting '0.1' (as a decimal floating-point number) in base 2 with :down rounding
|
898
|
+
# The:down rounding (truncation) could be used to show the exact value of the floating
|
899
|
+
# point but beware: if the value has not an exact representation in the output base this will
|
900
|
+
# lead to an infinite loop or repeating squence.
|
871
901
|
#
|
872
902
|
# When the +all+ parameters is used the result is not rounded (is truncated), and the round_up flag
|
873
903
|
# is set to indicate that nonzero digits exists beyond the returned digits; the possible values
|
874
904
|
# of the round_up flag are:
|
875
|
-
# * nil : the rest of digits are zero (the result is exact)
|
905
|
+
# * nil : the rest of digits are zero or repeat (the result is exact)
|
876
906
|
# * :lo : there exist non-zero digits beyond the significant ones (those returned), but
|
877
907
|
# the value is below the tie (the value must be rounded up only for :up rounding mode)
|
878
908
|
# * :tie : there exists exactly one nonzero digit after the significant and it is radix/2,
|
@@ -883,6 +913,7 @@ module Flt
|
|
883
913
|
# it is the rounding mode that applied to *input* preserves the original floating-point
|
884
914
|
# value (with the same precision as input).
|
885
915
|
# should be rounded-up.
|
916
|
+
#
|
886
917
|
def format(v, f, e, round_mode, p=nil, all=false)
|
887
918
|
context = v.class.context
|
888
919
|
# TODO: consider removing parameters f,e and using v.split instead
|
@@ -976,7 +1007,7 @@ module Flt
|
|
976
1007
|
return @k, @digits
|
977
1008
|
end
|
978
1009
|
|
979
|
-
attr_reader :round_up
|
1010
|
+
attr_reader :round_up, :repeat
|
980
1011
|
|
981
1012
|
|
982
1013
|
# Access rounded result of format operation: scaling (position of radix point) and digits
|
@@ -1078,17 +1109,67 @@ module Flt
|
|
1078
1109
|
@output_b**n
|
1079
1110
|
end
|
1080
1111
|
|
1112
|
+
def start_repetition_dectection
|
1113
|
+
@may_repeat = (@m_p == 0 || @m_m == 0)
|
1114
|
+
@n_iters = 0
|
1115
|
+
@rs = []
|
1116
|
+
end
|
1117
|
+
|
1118
|
+
ITERATIONS_BEFORE_KEEPING_TRACK_OF_REMAINDERS = 10000
|
1119
|
+
|
1120
|
+
# Detect indefinite repetitions in generate_max
|
1121
|
+
# returns the number of digits that are being repeated
|
1122
|
+
# (0 indicates the next digit would repeat and it would be a zero)
|
1123
|
+
def detect_repetitions(r)
|
1124
|
+
return nil unless @may_repeat
|
1125
|
+
@n_iters += 1
|
1126
|
+
if r == 0 && @m_p == 0
|
1127
|
+
repeat_count = 0
|
1128
|
+
elsif (@n_iters > ITERATIONS_BEFORE_KEEPING_TRACK_OF_REMAINDERS)
|
1129
|
+
if @rs.include?(r)
|
1130
|
+
repeat_count = @rs.index(r) - @rs.size
|
1131
|
+
else
|
1132
|
+
@rs << r
|
1133
|
+
end
|
1134
|
+
end
|
1135
|
+
if repeat_count
|
1136
|
+
raise InfiniteLoopError, "Infinite digit sequence." if @raise_on_repeat
|
1137
|
+
repeat_count
|
1138
|
+
else
|
1139
|
+
nil
|
1140
|
+
end
|
1141
|
+
end
|
1142
|
+
|
1143
|
+
def remove_redundant_repetitions
|
1144
|
+
if ITERATIONS_BEFORE_KEEPING_TRACK_OF_REMAINDERS > 0 && @repeat
|
1145
|
+
if @repeat < @digits.size
|
1146
|
+
repeating_digits = @digits[@repeat..-1]
|
1147
|
+
l = repeating_digits.size
|
1148
|
+
pos = @repeat - l
|
1149
|
+
while pos >= 0 && @digits[pos, l] == repeating_digits
|
1150
|
+
pos -= l
|
1151
|
+
end
|
1152
|
+
first_repeat = pos + l
|
1153
|
+
if first_repeat < @repeat
|
1154
|
+
@repeat = first_repeat
|
1155
|
+
@digits = @digits[0, @repeat+l]
|
1156
|
+
end
|
1157
|
+
end
|
1158
|
+
end
|
1159
|
+
@digits
|
1160
|
+
end
|
1161
|
+
|
1081
1162
|
def generate_max
|
1082
1163
|
@round_up = false
|
1083
1164
|
list = []
|
1084
1165
|
r, s, m_p, m_m, = @r, @s, @m_p, @m_m
|
1085
|
-
|
1166
|
+
|
1167
|
+
start_repetition_dectection
|
1168
|
+
|
1086
1169
|
loop do
|
1087
|
-
if
|
1088
|
-
|
1089
|
-
|
1090
|
-
else
|
1091
|
-
n_iters += 1
|
1170
|
+
if repeat_count = detect_repetitions(r)
|
1171
|
+
@repeat = list.size + repeat_count
|
1172
|
+
break
|
1092
1173
|
end
|
1093
1174
|
|
1094
1175
|
d,r = (r*@output_b).divmod(s)
|
@@ -1116,6 +1197,7 @@ module Flt
|
|
1116
1197
|
end
|
1117
1198
|
end
|
1118
1199
|
@digits = list
|
1200
|
+
remove_redundant_repetitions
|
1119
1201
|
end
|
1120
1202
|
|
1121
1203
|
def generate
|
data/lib/flt/version.rb
CHANGED
@@ -0,0 +1,197 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
|
2
|
+
|
3
|
+
|
4
|
+
class TestExact < Test::Unit::TestCase
|
5
|
+
|
6
|
+
|
7
|
+
def setup
|
8
|
+
initialize_context
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_binary_to_decimal_formatter
|
12
|
+
Flt::BinNum.context = Flt::BinNum::IEEEDoubleContext
|
13
|
+
formatter = Flt::Support::Formatter.new(BinNum.radix, BinNum.context.etiny, 10)
|
14
|
+
|
15
|
+
x = BinNum(0.1)
|
16
|
+
s, f, e = x.split
|
17
|
+
|
18
|
+
digits = formatter.format(x, f, e, :half_even, BinNum.context.precision, false)
|
19
|
+
assert_equal [1], digits
|
20
|
+
|
21
|
+
digits = formatter.format(x, f, e, :half_even, BinNum.context.precision, true)
|
22
|
+
assert_equal [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], digits
|
23
|
+
assert_equal :hi, formatter.round_up
|
24
|
+
|
25
|
+
digits = formatter.format(x, f, e, :up, BinNum.context.precision, false)
|
26
|
+
assert_equal [1], digits
|
27
|
+
|
28
|
+
assert_raise(Flt::Support::InfiniteLoopError) { formatter.format(x, f, e, :up, BinNum.context.precision, true) }
|
29
|
+
|
30
|
+
digits = formatter.format(x, f, e, :down, BinNum.context.precision, false)
|
31
|
+
assert_equal [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
32
|
+
digits
|
33
|
+
|
34
|
+
digits = formatter.format(x, f, e, :down, BinNum.context.precision, true)
|
35
|
+
assert_equal [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5, 8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5],
|
36
|
+
digits
|
37
|
+
|
38
|
+
x = BinNum(0.5)
|
39
|
+
s, f, e = x.split
|
40
|
+
|
41
|
+
digits = formatter.format(x, f, e, :half_even, BinNum.context.precision, false)
|
42
|
+
assert_equal [5], digits
|
43
|
+
|
44
|
+
digits = formatter.format(x, f, e, :half_even, BinNum.context.precision, true)
|
45
|
+
assert_equal [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], digits
|
46
|
+
refute formatter.round_up
|
47
|
+
|
48
|
+
digits = formatter.format(x, f, e, :up, BinNum.context.precision, false)
|
49
|
+
assert_equal [5], digits
|
50
|
+
|
51
|
+
assert_raise(Flt::Support::InfiniteLoopError) { formatter.format(x, f, e, :up, BinNum.context.precision, true) }
|
52
|
+
|
53
|
+
digits = formatter.format(x, f, e, :down, BinNum.context.precision, false)
|
54
|
+
assert_equal [5], digits
|
55
|
+
|
56
|
+
digits = formatter.format(x, f, e, :down, BinNum.context.precision, true)
|
57
|
+
assert_equal [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], digits
|
58
|
+
refute formatter.round_up
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_binary_to_repeating_decimal_formatter
|
62
|
+
Flt::BinNum.context = Flt::BinNum::IEEEDoubleContext
|
63
|
+
formatter = Flt::Support::Formatter.new(BinNum.radix, BinNum.context.etiny, 10, raise_on_repeat: false)
|
64
|
+
|
65
|
+
x = BinNum(0.1)
|
66
|
+
s, f, e = x.split
|
67
|
+
|
68
|
+
digits = formatter.format(x, f, e, :half_even, BinNum.context.precision, false)
|
69
|
+
assert_equal [1], digits
|
70
|
+
|
71
|
+
digits = formatter.format(x, f, e, :half_even, BinNum.context.precision, true)
|
72
|
+
assert_equal [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], digits
|
73
|
+
assert_equal :hi, formatter.round_up
|
74
|
+
refute formatter.repeat
|
75
|
+
|
76
|
+
digits = formatter.format(x, f, e, :up, BinNum.context.precision, false)
|
77
|
+
assert_equal [1], digits
|
78
|
+
|
79
|
+
assert_nothing_raised { formatter.format(x, f, e, :up, BinNum.context.precision, true) }
|
80
|
+
digits = formatter.format(x, f, e, :up, BinNum.context.precision, true)
|
81
|
+
assert_equal [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5, 8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5],
|
82
|
+
digits
|
83
|
+
refute formatter.round_up
|
84
|
+
assert_equal 55, formatter.repeat
|
85
|
+
|
86
|
+
digits = formatter.format(x, f, e, :down, BinNum.context.precision, false)
|
87
|
+
assert_equal [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
88
|
+
digits
|
89
|
+
|
90
|
+
digits = formatter.format(x, f, e, :down, BinNum.context.precision, true)
|
91
|
+
assert_equal [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5, 8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5],
|
92
|
+
digits
|
93
|
+
|
94
|
+
x = BinNum(0.5)
|
95
|
+
s, f, e = x.split
|
96
|
+
|
97
|
+
digits = formatter.format(x, f, e, :half_even, BinNum.context.precision, false)
|
98
|
+
assert_equal [5], digits
|
99
|
+
|
100
|
+
digits = formatter.format(x, f, e, :half_even, BinNum.context.precision, true)
|
101
|
+
assert_equal [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], digits
|
102
|
+
refute formatter.round_up
|
103
|
+
|
104
|
+
digits = formatter.format(x, f, e, :up, BinNum.context.precision, false)
|
105
|
+
assert_equal [5], digits
|
106
|
+
|
107
|
+
assert_nothing_raised { formatter.format(x, f, e, :up, BinNum.context.precision, true) }
|
108
|
+
digits = formatter.format(x, f, e, :up, BinNum.context.precision, true)
|
109
|
+
assert_equal [5], digits
|
110
|
+
refute formatter.round_up
|
111
|
+
assert_equal 1, formatter.repeat
|
112
|
+
|
113
|
+
digits = formatter.format(x, f, e, :down, BinNum.context.precision, false)
|
114
|
+
assert_equal [5], digits
|
115
|
+
|
116
|
+
digits = formatter.format(x, f, e, :down, BinNum.context.precision, true)
|
117
|
+
assert_equal [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], digits
|
118
|
+
refute formatter.round_up
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_decimal_to_binary_formatter
|
122
|
+
Flt::DecNum.context.precision = 8
|
123
|
+
formatter = Flt::Support::Formatter.new(DecNum.radix, DecNum.context.etiny, 2)
|
124
|
+
|
125
|
+
x = DecNum('0.1')
|
126
|
+
s, f, e = x.split
|
127
|
+
digits = formatter.format(x, f, e, :half_even, DecNum.context.precision, false)
|
128
|
+
assert_equal [1], digits
|
129
|
+
|
130
|
+
digits = formatter.format(x, f, e, :half_even, DecNum.context.precision, true)
|
131
|
+
assert_equal [0,1], digits
|
132
|
+
assert_equal :hi, formatter.round_up
|
133
|
+
|
134
|
+
x = DecNum('0.1000000')
|
135
|
+
s, f, e = x.split
|
136
|
+
|
137
|
+
digits = formatter.format(x, f, e, :half_even, DecNum.context.precision, false)
|
138
|
+
assert_equal [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1], digits
|
139
|
+
|
140
|
+
digits = formatter.format(x, f, e, :half_even, DecNum.context.precision, true)
|
141
|
+
assert_equal [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1], digits
|
142
|
+
assert_equal :hi, formatter.round_up
|
143
|
+
|
144
|
+
digits = formatter.format(x, f, e, :up, DecNum.context.precision, false)
|
145
|
+
assert_equal [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1], digits
|
146
|
+
|
147
|
+
assert_raise(Support::InfiniteLoopError) { formatter.format(x, f, e, :up, DecNum.context.precision, true) }
|
148
|
+
|
149
|
+
digits = formatter.format(x, f, e, :down, DecNum.context.precision, false)
|
150
|
+
assert_equal [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1], digits
|
151
|
+
|
152
|
+
assert_raise(Support::InfiniteLoopError) { formatter.format(x, f, e, :down, DecNum.context.precision, true) }
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_decimal_to_repeating_binary_formatter
|
156
|
+
Flt::DecNum.context.precision = 8
|
157
|
+
formatter = Flt::Support::Formatter.new(DecNum.radix, DecNum.context.etiny, 2, raise_on_repeat: false)
|
158
|
+
|
159
|
+
x = DecNum('0.1')
|
160
|
+
s, f, e = x.split
|
161
|
+
digits = formatter.format(x, f, e, :half_even, DecNum.context.precision, false)
|
162
|
+
assert_equal [1], digits
|
163
|
+
|
164
|
+
digits = formatter.format(x, f, e, :half_even, DecNum.context.precision, true)
|
165
|
+
assert_equal [0,1], digits
|
166
|
+
assert_equal :hi, formatter.round_up
|
167
|
+
|
168
|
+
x = DecNum('0.1000000')
|
169
|
+
s, f, e = x.split
|
170
|
+
|
171
|
+
digits = formatter.format(x, f, e, :half_even, DecNum.context.precision, false)
|
172
|
+
assert_equal [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1], digits
|
173
|
+
|
174
|
+
digits = formatter.format(x, f, e, :half_even, DecNum.context.precision, true)
|
175
|
+
assert_equal [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1], digits
|
176
|
+
assert_equal :hi, formatter.round_up
|
177
|
+
|
178
|
+
digits = formatter.format(x, f, e, :up, DecNum.context.precision, false)
|
179
|
+
assert_equal [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1], digits
|
180
|
+
|
181
|
+
assert_nothing_raised { formatter.format(x, f, e, :up, DecNum.context.precision, true) }
|
182
|
+
digits = formatter.format(x, f, e, :up, DecNum.context.precision, true)
|
183
|
+
assert_equal [1, 1, 0, 0], digits
|
184
|
+
refute formatter.round_up
|
185
|
+
assert_equal 0, formatter.repeat
|
186
|
+
|
187
|
+
digits = formatter.format(x, f, e, :down, DecNum.context.precision, false)
|
188
|
+
assert_equal [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1], digits
|
189
|
+
|
190
|
+
assert_nothing_raised { formatter.format(x, f, e, :down, DecNum.context.precision, true) }
|
191
|
+
digits = formatter.format(x, f, e, :down, DecNum.context.precision, true)
|
192
|
+
assert_equal [1, 1, 0, 0], digits
|
193
|
+
refute formatter.round_up
|
194
|
+
assert_equal 0, formatter.repeat
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Javier Goizueta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- test/test_epsilon.rb
|
88
88
|
- test/test_exact.rb
|
89
89
|
- test/test_flags.rb
|
90
|
+
- test/test_formatter.rb
|
90
91
|
- test/test_multithreading.rb
|
91
92
|
- test/test_num_constructor.rb
|
92
93
|
- test/test_odd_even.rb
|
@@ -137,6 +138,7 @@ test_files:
|
|
137
138
|
- test/test_epsilon.rb
|
138
139
|
- test/test_exact.rb
|
139
140
|
- test/test_flags.rb
|
141
|
+
- test/test_formatter.rb
|
140
142
|
- test/test_multithreading.rb
|
141
143
|
- test/test_num_constructor.rb
|
142
144
|
- test/test_odd_even.rb
|