flt 1.3.3 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a623d39842de7043c3004b02fe86bf20b4fb6491
4
- data.tar.gz: a21afce102fa26145f8f24b8661d6b9bfddb2ae4
3
+ metadata.gz: 58bd070debe5638c64334230eb8e5d87176001bd
4
+ data.tar.gz: 71adc3e996232e211bd521ee64ef14b1e6f3f100
5
5
  SHA512:
6
- metadata.gz: bfe19f6b32df81f96b39d1b58b8845c402c66fc3f20b0e4e6cbc45cc4593f1d5e3d37aea6c0f3cbf02a15ef30aae75805ffefb740099fd41bc729f99f0de9bf3
7
- data.tar.gz: e4077b0fdcd3ecd337af25b8fec87c47cde43003b89dff3c8621fe4f434589a0f73a726aa32389e40251b47c714db07f94d6845de62bc550cdc9f441a85d1321
6
+ metadata.gz: 19c292ce44adafdf320693681e5e563cf5a73763941ca3de66cf6de654ad50db9b2f69409acb91f78ae1a18f6509399331fd0bf742da51acf28ddc79115c639d
7
+ data.tar.gz: 6c060e62ce10a9489bfae7d7cb5105845bdc4ff04cfc0e790e64962315690707a3efd8a4b831d63cc2bffc680587315ebb0a72c6643d5f0f191e189e490d31e8
@@ -1,3 +1,12 @@
1
+ == 1.3.4 2014-10-27
2
+
3
+ * New features
4
+ - Context methods necessary_digits and representable_digits
5
+ - Assign :exact as the precision value to define an :exact context
6
+ - Constructors for nan, infinite, zero replicated in context
7
+ - Hexadecimal (%A) representation of binary floating point numbers
8
+ - Support.adjust_digits (to be used in Numerals gem)
9
+
1
10
  == 1.3.3 2014-10-13
2
11
 
3
12
  Formatter has a new raise_on_repeat options
@@ -127,6 +127,10 @@ class Flt::FloatContext
127
127
  (sign < 0) ? -1.0/0.0 : 1.0/0.0 # Ruby 1.9.2: (sing < 0) ? -Float::INFINITY : Float::INFINITY
128
128
  end
129
129
 
130
+ def one_half
131
+ 0.5
132
+ end
133
+
130
134
  def int_radix_power(n)
131
135
  1 << n
132
136
  end
@@ -475,6 +479,25 @@ class Flt::FloatContext
475
479
  end
476
480
  end
477
481
 
482
+ def representable_digits(b)
483
+ if b == 10
484
+ Float::DIG
485
+ elsif b == radix
486
+ precision
487
+ else
488
+ ((precision-1)*log(radix, b)).floor
489
+ end
490
+ end
491
+
492
+ def necessary_digits(b)
493
+ if b == 10
494
+ Float::DECIMAL_DIG
495
+ elsif b == radix
496
+ precision
497
+ else
498
+ (precision*log(radix, b)).ceil + 1
499
+ end
500
+ end
478
501
 
479
502
  end
480
503
 
@@ -580,7 +580,7 @@ class Num < Numeric
580
580
  # If 0 is set the precision turns to be exact.
581
581
  def precision=(n)
582
582
  @precision = n
583
- @exact = false unless n==0
583
+ @exact = false
584
584
  update_precision
585
585
  n
586
586
  end
@@ -624,9 +624,12 @@ class Num < Numeric
624
624
  @clamp = options[:clamp ] unless options[:clamp ].nil?
625
625
  @exact = options[:exact ] unless options[:exact ].nil?
626
626
  @angle = options[:angle ] unless options[:angle ].nil?
627
- @precision += options[:extra_precision] unless options[:extra_precision].nil?
628
627
  update_precision
628
+ if options[:extra_precision] && !@exact
629
+ @precision += options[:extra_precision]
630
+ end
629
631
  end
632
+ self
630
633
  end
631
634
 
632
635
  attr_reader :coercible_type_handlers, :conversions
@@ -1148,6 +1151,56 @@ class Num < Numeric
1148
1151
  _convert(x).zero?
1149
1152
  end
1150
1153
 
1154
+ # Maximum number of base b digits that can be stored in a context floating point number
1155
+ # and then preserved when converted back to base b.
1156
+ #
1157
+ # To store a base b number in a floating point number and be able to get then back exactly
1158
+ # the number cannot have more than these significant digits.
1159
+ def representable_digits(b)
1160
+ unless exact?
1161
+ if b == radix
1162
+ precision
1163
+ else
1164
+ ((precision-1)*log(radix, b)).floor
1165
+ end
1166
+ end
1167
+ end
1168
+
1169
+ # Mininum number of base b digits necessary to store any context floating point number
1170
+ # while being able to convert the digits back to the same exact context floating point number
1171
+ #
1172
+ # To convert any floating point number to base b and be able to round the result back to
1173
+ # the same floating point number, at least this many base b digits are needed.
1174
+ def necessary_digits(b)
1175
+ unless exact?
1176
+ if b == radix
1177
+ precision
1178
+ else
1179
+ (precision*log(radix, b)).ceil + 1
1180
+ end
1181
+ end
1182
+ end
1183
+
1184
+ # A floating-point number with value zero and the specified sign
1185
+ def zero(sign = +1)
1186
+ num_class.zero(sign)
1187
+ end
1188
+
1189
+ # A floating-point infinite number with the specified sign
1190
+ def infinity(sign = +1)
1191
+ num_class.infinity(sign)
1192
+ end
1193
+
1194
+ # A floating-point NaN (not a number)
1195
+ def nan
1196
+ num_class.nan
1197
+ end
1198
+
1199
+ # One half: 1/2
1200
+ def one_half
1201
+ num_class.one_half
1202
+ end
1203
+
1151
1204
  private
1152
1205
 
1153
1206
  def _convert(x)
@@ -1164,13 +1217,14 @@ class Num < Numeric
1164
1217
  elsif @emin && !@emax
1165
1218
  @emax = 1 - @emin
1166
1219
  end
1167
- if @exact || @precision==0
1220
+ if @exact || @precision == 0 || @precision == :exact
1168
1221
  quiet = (@exact == :quiet)
1169
1222
  @exact = true
1170
1223
  @precision = 0
1171
1224
  @traps << Inexact unless quiet
1172
1225
  @ignored_flags[Inexact] = false
1173
1226
  else
1227
+ @exact = false
1174
1228
  @traps[Inexact] = false
1175
1229
  end
1176
1230
  end
@@ -1398,7 +1452,7 @@ class Num < Numeric
1398
1452
  options.delete(:exponent) || 0]
1399
1453
  end
1400
1454
  mode ||= options && options.delete(:mode)
1401
- base = (options && options.delete(:base)) || 10
1455
+ base = (options && options.delete(:base))
1402
1456
  context = options if context.nil? && options && !options.empty?
1403
1457
  context = define_context(context)
1404
1458
 
@@ -1434,7 +1488,7 @@ class Num < Numeric
1434
1488
  @sign,@coeff,@exp = context.exception(ConversionSyntax, "no trailing or leading whitespace is permitted").split
1435
1489
  return
1436
1490
  end
1437
- m = _parser(arg)
1491
+ m = _parser(arg, base: base)
1438
1492
  if m.nil?
1439
1493
  @sign,@coeff,@exp = context.exception(ConversionSyntax, "Invalid literal for DecNum: #{arg.inspect}").split
1440
1494
  return
@@ -1449,12 +1503,18 @@ class Num < Numeric
1449
1503
  intpart = ''
1450
1504
  fracpart = m.onlyfrac
1451
1505
  end
1506
+ fracpart ||= ''
1507
+ base = m.base
1452
1508
  exp = m.exp.to_i
1453
- if fracpart
1454
- coeff = (intpart+fracpart).to_i(base)
1455
- exp -= fracpart.size
1509
+ coeff = (intpart+fracpart).to_i(base)
1510
+ if m.exp_base && m.exp_base != base
1511
+ # The exponent uses a different base;
1512
+ # compute exponent in base; assume base = exp_base**k
1513
+ k = Math.log(base, m.exp_base).round
1514
+ exp -= fracpart.size*k
1515
+ base = m.exp_base
1456
1516
  else
1457
- coeff = intpart.to_i(base)
1517
+ exp -= fracpart.size
1458
1518
  end
1459
1519
 
1460
1520
  if false
@@ -3656,14 +3716,27 @@ class Num < Numeric
3656
3716
  # If it is not passed and :all_digits is true, then :rounding or the context rounding mode
3657
3717
  # will be used.
3658
3718
  #
3659
- # Note that when :base=>10 (the default) we're regarding the binary number x
3719
+ # Note that when :base is different from the floating point radix,
3720
+ # we're regarding the floating point number x
3660
3721
  # as an approximation with x.number_of_digits precision and showing that
3661
3722
  # inexact value in decimal without introducing additional precision.
3662
- # If the exact value of the number expressed in decimal is desired (we consider
3723
+ #
3724
+ # If the exact value of the number expressed in other base is desired (we consider
3663
3725
  # the Flt an exact number), this can be done with Num.convert_exact.
3726
+ #
3727
+ # The :hex_bin option produces the %A/%a format of printf, which sho2 the significand
3728
+ # as an hexadecimal number and the binary exponent in decimal.
3729
+ #
3664
3730
  def format(num_context, options={})
3665
3731
  # TODO: support options (base, all_digits, any_rounding, eng) and context options in the same hash
3666
3732
  output_radix = options[:base] || 10
3733
+ output_exp_radix = options[:exp_base]
3734
+ if output_radix == :hex_bin
3735
+ output_radix = 16
3736
+ output_exp_radix = 2
3737
+ first_digit_1 = true
3738
+ end
3739
+ output_exp_radix ||= output_radix
3667
3740
  rounding = options[:rounding]
3668
3741
  all_digits = options[:all_digits]
3669
3742
  eng = options[:eng]
@@ -3686,12 +3759,40 @@ class Num < Numeric
3686
3759
  rounding ||= context.rounding
3687
3760
  output_rounding ||= rounding
3688
3761
 
3689
- if output_radix == num_class.radix && !all_digits
3762
+ if output_radix != output_exp_radix
3763
+ k = Math.log(output_radix, output_exp_radix).round
3764
+ if output_radix != output_exp_radix**k
3765
+ raise "When different bases are used for the coefficient and exponent, the first must be a power of the second"
3766
+ end
3767
+ end
3768
+
3769
+ if output_exp_radix == num_class.radix && !all_digits && output_radix != output_exp_radix
3770
+ if first_digit_1
3771
+ # make the first digit a 1
3772
+ c = @coeff
3773
+ exp = integral_exponent
3774
+ nb = _nbits(c)
3775
+ r = (nb % k)
3776
+ d = (k + 1 - r) % k
3777
+ if d != 0
3778
+ c <<= d
3779
+ exp -= d
3780
+ end
3781
+ else
3782
+ c = @coeff
3783
+ exp = integral_exponent
3784
+ end
3785
+ ds = c.to_s(output_radix)
3786
+ n_ds = ds.size
3787
+ leftdigits = exp + n_ds
3788
+ exp_radix = num_class.radix
3789
+ elsif output_radix == num_class.radix && !all_digits && output_radix == output_exp_radix
3690
3790
  # show exactly inner representation and precision
3691
3791
  ds = @coeff.to_s(output_radix)
3692
3792
  n_ds = ds.size
3693
3793
  exp = integral_exponent
3694
3794
  leftdigits = exp + n_ds
3795
+ exp_radix = num_class.radix
3695
3796
  else
3696
3797
  p = self.number_of_digits # context.precision
3697
3798
  formatter = Flt::Support::Formatter.new(num_class.radix, context.etiny, output_radix)
@@ -3702,17 +3803,51 @@ class Num < Numeric
3702
3803
  n_ds = ds.size
3703
3804
  exp = dec_pos - n_ds
3704
3805
  leftdigits = dec_pos
3806
+ exp_radix = output_radix
3705
3807
  end
3706
3808
 
3707
- # TODO: DRY (this code is duplicated in num_class#format)
3708
- if exp<=0 && leftdigits>-6
3709
- dotplace = leftdigits
3710
- elsif !eng
3711
- dotplace = 1
3712
- elsif @coeff==0
3713
- dotplace = (leftdigits+1)%3 - 1
3809
+ # TODO: this doesn't need to be so ugly...
3810
+ if output_exp_radix == 2 && output_radix == 16
3811
+ a_format = true
3812
+ digits_prefix = "0x"
3813
+ exp_letter = (context.capitals ? 'P' : 'p')
3814
+ show_exp = true
3815
+ else
3816
+ a_format = false
3817
+ digits_prefix = ""
3818
+ exp_letter = (context.capitals ? 'E' : 'e')
3819
+ show_exp = false
3820
+ end
3821
+
3822
+ if output_exp_radix != exp_radix
3823
+ # k = Math.log(exp_radix, output_exp_radix).round
3824
+ if leftdigits != 1
3825
+ exp += (ds.size - 1)
3826
+ leftdigits = 1
3827
+ dotplace = 1
3828
+ end
3829
+ exp *= k
3830
+ elsif a_format
3831
+ # k = Math.log(output_radix, output_exp_radix).round
3832
+ if leftdigits != 1
3833
+ exp += (ds.size - 1)*4
3834
+ leftdigits = 1
3835
+ dotplace = 1
3836
+ ds = ds[0...-1] while ds[-1,1] == '0' && ds.size>1
3837
+ n_ds = ds.size
3838
+ end
3714
3839
  else
3715
- dotplace = (leftdigits-1)%3 + 1
3840
+ # TODO: DRY (this code is duplicated in num_class#format)
3841
+ if exp<=0 && leftdigits>-6
3842
+ dotplace = leftdigits
3843
+ elsif !eng
3844
+ dotplace = 1
3845
+ elsif @coeff==0
3846
+ dotplace = (leftdigits+1)%3 - 1
3847
+ else
3848
+ dotplace = (leftdigits-1)%3 + 1
3849
+ end
3850
+ exp = leftdigits-dotplace
3716
3851
  end
3717
3852
 
3718
3853
  if dotplace <=0
@@ -3726,14 +3861,13 @@ class Num < Numeric
3726
3861
  fracpart = '.' + ds[dotplace..-1]
3727
3862
  end
3728
3863
 
3729
- if leftdigits == dotplace
3864
+ if exp == 0 && !show_exp
3730
3865
  e = ''
3731
3866
  else
3732
- e = (context.capitals ? 'E' : 'e') + "%+d"%(leftdigits-dotplace)
3867
+ e = exp_letter + "%+d"%(exp)
3733
3868
  end
3734
3869
 
3735
- sgn + intpart + fracpart + e
3736
-
3870
+ sgn + digits_prefix + intpart + fracpart + e
3737
3871
  end
3738
3872
 
3739
3873
  # Auxiliar Methods
@@ -4017,11 +4151,20 @@ class Num < Numeric
4017
4151
  end
4018
4152
 
4019
4153
  # Parse numeric text literals (internal use)
4020
- def _parser(txt)
4154
+ def _parser(txt, options={})
4155
+ base = options[:base]
4021
4156
  md = /^\s*([-+])?(?:(?:(\d+)(?:\.(\d*))?|\.(\d+))(?:E([-+]?\d+))?|Inf(?:inity)?|(s)?NaN(\d*))\s*$/i.match(txt)
4022
4157
  if md
4158
+ base ||= 10
4023
4159
  OpenStruct.new :sign=>md[1], :int=>md[2], :frac=>md[3], :onlyfrac=>md[4], :exp=>md[5],
4024
- :signal=>md[6], :diag=>md[7]
4160
+ :signal=>md[6], :diag=>md[7], :base=>base
4161
+ else
4162
+ md = /^\s*([-+])?0x(?:(?:([\da-f]+)(?:\.([\da-f]*))?|\.([\da-f]+))(?:P([-+]?\d+))?)\s*$/i.match(txt)
4163
+ if md
4164
+ base = 16
4165
+ OpenStruct.new :sign=>md[1], :int=>md[2], :frac=>md[3], :onlyfrac=>md[4], :exp=>md[5],
4166
+ :signal=>nil, :diag=>nil, :base=>base, :exp_base=>2
4167
+ end
4025
4168
  end
4026
4169
  end
4027
4170
 
@@ -357,6 +357,51 @@ module Flt
357
357
  round_mode
358
358
  end
359
359
 
360
+ # Adjust truncated digits based on the rounding mode (:round_mode option)
361
+ # and on the information about the following digits contained in the :round_up
362
+ # parameter (nil for only zeros, :lo for nonzero values below tie, :tie for a :tie
363
+ # and :hi for nonzero digits over the tie). Other parameters: :negative to consider
364
+ # the number negative, :base the base of the number.
365
+ def adjust_digits(dec_pos, digits, options={})
366
+ round_mode = options[:round_mode]
367
+ negative = options[:negative]
368
+ round_up = options[:round_up]
369
+ base = options[:base]
370
+ round_mode = simplified_round_mode(round_mode, negative)
371
+
372
+ increment = (round_up && (round_mode != :down)) &&
373
+ ((round_mode == :up) ||
374
+ (round_up == :hi) ||
375
+ ((round_up == :tie) &&
376
+ ((round_mode==:half_up) ||
377
+ ((round_mode==:half_even) && ((digits.last % 2)==1)))))
378
+
379
+ if increment
380
+ digits = digits.dup
381
+ # carry = increment ? 1 : 0
382
+ # digits = digits.reverse.map{|d| d += carry; d>=base ? 0 : (carry=0;d)}.reverse
383
+ # if carry != 0
384
+ # digits.unshift carry
385
+ # dec_pos += 1
386
+ # end
387
+ i = digits.size - 1
388
+ while i>=0
389
+ digits[i] += 1
390
+ if digits[i] == base
391
+ digits[i] = 0
392
+ else
393
+ break
394
+ end
395
+ i -= 1
396
+ end
397
+ if i<0
398
+ dec_pos += 1
399
+ digits.unshift 1
400
+ end
401
+ end
402
+ [dec_pos, digits]
403
+ end
404
+
360
405
  # Floating-point reading and printing (from/to text literals).
361
406
  #
362
407
  # Here are methods for floating-point reading, using algorithms by William D. Clinger, and
@@ -1009,47 +1054,14 @@ module Flt
1009
1054
 
1010
1055
  attr_reader :round_up, :repeat
1011
1056
 
1012
-
1013
1057
  # Access rounded result of format operation: scaling (position of radix point) and digits
1014
1058
  def adjusted_digits(round_mode)
1015
- round_mode = Support.simplified_round_mode(round_mode, @minus)
1016
1059
  if @adjusted_digits.nil? && !@digits.nil?
1017
- increment = (@round_up && (round_mode != :down)) &&
1018
- ((round_mode == :up) ||
1019
- (@round_up == :hi) ||
1020
- ((@round_up == :tie) &&
1021
- ((round_mode==:half_up) || ((round_mode==:half_even) && ((@digits.last % 2)==1)))))
1022
- # increment = (@round_up == :tie) || (@round_up == :hi) # old behaviour (:half_up)
1023
- if increment
1024
- base = @output_b
1025
- dec_pos = @k
1026
- digits = @digits.dup
1027
- # carry = increment ? 1 : 0
1028
- # digits = digits.reverse.map{|d| d += carry; d>=base ? 0 : (carry=0;d)}.reverse
1029
- # if carry != 0
1030
- # digits.unshift carry
1031
- # dec_pos += 1
1032
- # end
1033
- i = digits.size - 1
1034
- while i>=0
1035
- digits[i] += 1
1036
- if digits[i] == base
1037
- digits[i] = 0
1038
- else
1039
- break
1040
- end
1041
- i -= 1
1042
- end
1043
- if i<0
1044
- dec_pos += 1
1045
- digits.unshift 1
1046
- end
1047
- @adjusted_k = dec_pos
1048
- @adjusted_digits = digits
1049
- else
1050
- @adjusted_k = @k
1051
- @adjusted_digits = @digits
1052
- end
1060
+ @adjusted_k, @adjusted_digits = Support.adjust_digits(@k, @digits,
1061
+ :round_mode => round_mode,
1062
+ :negative => @minus,
1063
+ :round_up => @round_up,
1064
+ :base => @output_b)
1053
1065
  end
1054
1066
  return @adjusted_k, @adjusted_digits
1055
1067
  end
@@ -1,3 +1,3 @@
1
1
  module Flt
2
- VERSION = "1.3.3"
2
+ VERSION = "1.3.4"
3
3
  end
@@ -0,0 +1,55 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+
4
+ class TestBaseDigits < Test::Unit::TestCase
5
+
6
+
7
+ def test_number_of_digits_in_other_base
8
+
9
+ assert_equal Float::DIG, Float.context.representable_digits(10)
10
+ assert_equal Float::DECIMAL_DIG, Float.context.necessary_digits(10)
11
+
12
+ if defined?(BinNum::FloatContext)
13
+ assert_equal Float::DIG, BinNum::FloatContext.representable_digits(10)
14
+ assert_equal Float::DECIMAL_DIG, BinNum::FloatContext.necessary_digits(10)
15
+ end
16
+
17
+ assert_equal 6, BinNum::IEEESingleContext.representable_digits(10)
18
+ assert_equal 9, BinNum::IEEESingleContext.necessary_digits(10)
19
+
20
+ assert_equal 15, BinNum::IEEEDoubleContext.representable_digits(10)
21
+ assert_equal 17, BinNum::IEEEDoubleContext.necessary_digits(10)
22
+
23
+ assert_equal 18, BinNum::IEEEExtendedContext.representable_digits(10)
24
+ assert_equal 21, BinNum::IEEEExtendedContext.necessary_digits(10)
25
+
26
+
27
+ [10,15,20,100].each do |precision|
28
+ DecNum.context(precision: precision) do
29
+ assert_equal precision, DecNum.context.representable_digits(10)
30
+ assert_equal precision, DecNum.context.necessary_digits(10)
31
+ end
32
+
33
+ BinNum.context(precision: precision) do
34
+ assert_equal precision, BinNum.context.representable_digits(2)
35
+ assert_equal precision, BinNum.context.necessary_digits(2)
36
+ end
37
+ end
38
+
39
+ DecNum.context(exact: true) do
40
+ assert_nil DecNum.context.representable_digits(10)
41
+ assert_nil DecNum.context.necessary_digits(10)
42
+ assert_nil DecNum.context.representable_digits(2)
43
+ assert_nil DecNum.context.necessary_digits(2)
44
+ end
45
+
46
+ BinNum.context(exact: true) do
47
+ assert_nil BinNum.context.representable_digits(10)
48
+ assert_nil BinNum.context.necessary_digits(10)
49
+ assert_nil BinNum.context.representable_digits(2)
50
+ assert_nil BinNum.context.necessary_digits(2)
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -381,6 +381,26 @@ class TestBasic < Test::Unit::TestCase
381
381
  assert_equal(-1, neg.sign)
382
382
  end
383
383
 
384
+ def test_special_constructors
385
+ [DecNum, BinNum, Float].each do |num_class|
386
+ context = num_class.context
387
+ assert context.nan.nan?
388
+ assert context.zero.zero?
389
+ assert_equal +1, context.sign(context.zero)
390
+ assert context.zero(+1).zero?
391
+ assert_equal +1, context.sign(context.zero(+1))
392
+ assert context.zero(-1).zero?
393
+ assert_equal -1, context.sign(context.zero(-1))
394
+ assert context.infinity.infinite?
395
+ assert_equal +1, context.sign(context.infinity)
396
+ assert context.infinity(+1).infinite?
397
+ assert_equal +1, context.sign(context.infinity(+1))
398
+ assert context.infinity(-1).infinite?
399
+ assert_equal -1, context.sign(context.infinity(-1))
400
+ assert_equal context.Num(1)/2, context.one_half
401
+ end
402
+ end
403
+
384
404
  def test_context_parameters
385
405
  #DecNum.context = DecNum.Context
386
406
  DecNum.context.precision = 3
@@ -144,4 +144,22 @@ class TestExact < Test::Unit::TestCase
144
144
 
145
145
  end
146
146
 
147
+ def test_exact_precision
148
+ DecNum.context.precision = 10
149
+ refute DecNum.context.exact?
150
+ assert_equal 10, DecNum.context.precision
151
+ DecNum.context(exact: true) do
152
+ assert DecNum.context.exact?
153
+ assert_equal 0, DecNum.context.precision
154
+ end
155
+ refute DecNum.context.exact?
156
+ assert_equal 10, DecNum.context.precision
157
+ DecNum.context(precision: :exact) do
158
+ assert DecNum.context.exact?
159
+ assert_equal 0, DecNum.context.precision
160
+ end
161
+ refute DecNum.context.exact?
162
+ assert_equal 10, DecNum.context.precision
163
+ end
164
+
147
165
  end
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+ class TestHexFormat< Test::Unit::TestCase
4
+
5
+ def setup
6
+ @hex_test_data = [0.1, 1.0/3, 0.1e10, 1e10/3.0, 0.1e-10, 1e-10/3.0, 123456.789,
7
+ -0.1, -1.0/3, -0.1e10, -1e10/3.0, -0.1e-10, -1e-10/3.0, -123456.789,
8
+ Float::MAX, -Float::MIN, Float::MIN_D, Float::MAX_D, Float::MIN_D,
9
+ -Float::MIN_D, -Float::MAX_D, -Float::MIN_D,
10
+ Float.context.next_plus(0.1), Float.context.next_minus(0.1),
11
+ -Float.context.next_plus(0.1), -Float.context.next_minus(0.1),
12
+ 0.5, Float.context.next_plus(0.5), Float.context.next_minus(0.5),
13
+ -0.5, -Float.context.next_plus(0.5), -Float.context.next_minus(0.5),
14
+ 1E22, -1E22, 64.1, -64.1]
15
+ end
16
+
17
+ def test_hex_input
18
+ if RUBY_VERSION >= "1.9.2" # luckily there's no 1.9.10!
19
+ BinNum.context(BinNum::FloatContext) do
20
+ @hex_test_data.each do |number|
21
+ hex_upcase = "%A" % number
22
+ hex_downcase = "%a" % number
23
+ assert_equal number, BinNum(hex_upcase).to_f, "Read #{hex_upcase} (number)"
24
+ assert_equal number, BinNum(hex_downcase).to_f, "Read #{hex_downcase} (number)"
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ def test_hex_output
31
+ if RUBY_VERSION >= "1.9.2" # luckily there's no 1.9.10!
32
+ BinNum.context(BinNum::FloatContext) do
33
+ @hex_test_data.each do |number|
34
+ hex_upcase = "%A" % number
35
+ number = BinNum(number)
36
+ # text = number.to_s(:base => :hex_bin, :all_digits => false, :output_rounding => BinNum.context.rounding)
37
+ text = number.to_s(:base => :hex_bin, :all_digits => false, :output_rounding => nil)
38
+ assert_equal hex_upcase, text.upcase, "Write #{hex_upcase} (number)"
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ 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.3
4
+ version: 1.3.4
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-13 00:00:00.000000000 Z
11
+ date: 2014-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -76,6 +76,7 @@ files:
76
76
  - test/generate_trig_data.rb
77
77
  - test/helper.rb
78
78
  - test/reader.rb
79
+ - test/test_base_digits.rb
79
80
  - test/test_basic.rb
80
81
  - test/test_bin.rb
81
82
  - test/test_bin_arithmetic.rb
@@ -88,6 +89,7 @@ files:
88
89
  - test/test_exact.rb
89
90
  - test/test_flags.rb
90
91
  - test/test_formatter.rb
92
+ - test/test_hex_format.rb
91
93
  - test/test_multithreading.rb
92
94
  - test/test_num_constructor.rb
93
95
  - test/test_odd_even.rb
@@ -127,6 +129,7 @@ test_files:
127
129
  - test/generate_trig_data.rb
128
130
  - test/helper.rb
129
131
  - test/reader.rb
132
+ - test/test_base_digits.rb
130
133
  - test/test_basic.rb
131
134
  - test/test_bin.rb
132
135
  - test/test_bin_arithmetic.rb
@@ -139,6 +142,7 @@ test_files:
139
142
  - test/test_exact.rb
140
143
  - test/test_flags.rb
141
144
  - test/test_formatter.rb
145
+ - test/test_hex_format.rb
142
146
  - test/test_multithreading.rb
143
147
  - test/test_num_constructor.rb
144
148
  - test/test_odd_even.rb