summaryrefslogtreecommitdiff
path: root/ext/bigdecimal/lib/bigdecimal/util.rb
blob: 2781150557e7736089d5a996cf02d102c3824e39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# BigDecimal extends the native Integer class to provide the #to_d method.
#
# When you require the BigDecimal library in your application, this methodwill
# be available on Integer objects.
class Integer < Numeric
  # call-seq:
  #     int.to_d  -> bigdecimal
  #
  # Convert +int+ to a BigDecimal and return it.
  #
  #     require 'bigdecimal'
  #     require 'bigdecimal/util'
  #
  #     42.to_d
  #     # => #<BigDecimal:1008ef070,'0.42E2',9(36)>
  #
  def to_d
    BigDecimal(self)
  end
end

# BigDecimal extends the native Float class to provide the #to_d method.
#
# When you require BigDecimal in your application, this method will be
# available on Float objects.
class Float < Numeric
  # call-seq:
  #     flt.to_d  -> bigdecimal
  #
  # Convert +flt+ to a BigDecimal and return it.
  #
  #     require 'bigdecimal'
  #     require 'bigdecimal/util'
  #
  #     0.5.to_d
  #     # => #<BigDecimal:1dc69e0,'0.5E0',9(18)>
  #
  def to_d(precision=nil)
    BigDecimal(self, precision || Float::DIG)
  end
end

# BigDecimal extends the native String class to provide the #to_d method.
#
# When you require BigDecimal in your application, this method will be
# available on String objects.
class String
  # call-seq:
  #     string.to_d  -> bigdecimal
  #
  # Convert +string+ to a BigDecimal and return it.
  #
  #     require 'bigdecimal'
  #     require 'bigdecimal/util'
  #
  #     "0.5".to_d
  #     # => #<BigDecimal:1dc69e0,'0.5E0',9(18)>
  #
  def to_d
    BigDecimal(self)
  end
end

# BigDecimal extends the native Numeric class to provide the #to_digits and
# #to_d methods.
#
# When you require BigDecimal in your application, this method will be
# available on BigDecimal objects.
class BigDecimal < Numeric
  # call-seq:
  #     a.to_digits -> string
  #
  # Converts a BigDecimal to a String of the form "nnnnnn.mmm".
  # This method is deprecated; use BigDecimal#to_s("F") instead.
  #
  #     require 'bigdecimal'
  #     require 'bigdecimal/util'
  #
  #     d = BigDecimal.new("3.14")
  #     d.to_digits
  #     # => "3.14"
  def to_digits
    if self.nan? || self.infinite? || self.zero?
      self.to_s
    else
      i       = self.to_i.to_s
      _,f,_,z = self.frac.split
      i + "." + ("0"*(-z)) + f
    end
  end

  # call-seq:
  #     a.to_d -> bigdecimal
  #
  # Returns self.
  def to_d
    self
  end
end

# BigDecimal extends the native Rational class to provide the #to_d method.
#
# When you require BigDecimal in your application, this method will be
# available on Rational objects.
class Rational < Numeric
  # call-seq:
  #   r.to_d        -> bigdecimal
  #   r.to_d(precision)   -> bigdecimal
  #
  # Converts a Rational to a BigDecimal.
  #
  # The required +precision+ parameter is used to determine the amount of
  # significant digits for the result. See BigDecimal#div for more information,
  # as it is used along with the #denominator and the +precision+ for
  # parameters.
  #
  #   r = (22/7.0).to_r
  #   # => (7077085128725065/2251799813685248)
  #   r.to_d
  #   # => #<BigDecimal:1a52bd8,'0.3142857142 8571427937 0154144999 105E1',45(63)>
  #   r.to_d(3)
  #   # => #<BigDecimal:1a44d08,'0.314E1',18(36)>
  def to_d(precision)
    if precision <= 0
      raise ArgumentError, "negative precision"
    end
    num = self.numerator
    BigDecimal(num).div(self.denominator, precision)
  end
end