flt 1.3.3 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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