Class: BigDecimal

Inherits:
Numeric show all
Defined in:
opal/stdlib/bigdecimal.rb,
opal/stdlib/bigdecimal.rb,
opal/stdlib/bigdecimal/util.rb,
opal/stdlib/bigdecimal/bignumber.js.rb

Constant Summary collapse

ROUND_MODE =
256
ROUND_UP =

NOTE: the numeric values of the ROUND_* constants follow BigNumber.js, they are NOT the same as MRI

0
ROUND_DOWN =
1
ROUND_CEILING =
2
ROUND_FLOOR =
3
ROUND_HALF_UP =
4
ROUND_HALF_DOWN =
5
ROUND_HALF_EVEN =
6
SIGN_NaN =
0
SIGN_POSITIVE_ZERO =
1
SIGN_NEGATIVE_ZERO =
-1
SIGN_POSITIVE_FINITE =
2
SIGN_NEGATIVE_FINITE =
-2
SIGN_POSITIVE_INFINITE =
3
SIGN_NEGATIVE_INFINITE =
-3

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Numeric

#to_json, #to_n

Constructor Details

#initialize(initial, digits = 0) ⇒ BigDecimal

Returns a new instance of BigDecimal.



55
56
57
# File 'opal/stdlib/bigdecimal.rb', line 55

def initialize(initial, digits = 0)
  @bignumber = JS.new(BigNumber, initial)
end

Instance Attribute Details

#bignumberObject (readonly)

Returns the value of attribute bignumber.



53
54
55
# File 'opal/stdlib/bigdecimal.rb', line 53

def bignumber
  @bignumber
end

Class Method Details

.limit(digits = nil) ⇒ Object



40
41
42
43
# File 'opal/stdlib/bigdecimal.rb', line 40

def self.limit(digits = nil)
  @digits = digits if digits
  @digits
end

.mode(mode, value = nil) ⇒ Object



45
46
47
48
49
50
51
# File 'opal/stdlib/bigdecimal.rb', line 45

def self.mode(mode, value = nil)
  case mode
  when ROUND_MODE
    @round_mode = value if value
    @round_mode || ROUND_HALF_UP
  end
end

.new(*args, **kwargs) ⇒ Object



14
15
16
17
# File 'opal/stdlib/bigdecimal.rb', line 14

def BigDecimal.new(*args, **kwargs)
  warn 'BigDecimal.new is deprecated; use BigDecimal() method instead.', uplevel: 1
  BigDecimal(*args, **kwargs)
end

Instance Method Details

#<(other) ⇒ Object



82
83
84
85
# File 'opal/stdlib/bigdecimal.rb', line 82

def <(other)
  return false if nan? || other && other.nan?
  super
end

#<=(other) ⇒ Object



87
88
89
90
# File 'opal/stdlib/bigdecimal.rb', line 87

def <=(other)
  return false if nan? || other && other.nan?
  super
end

#<=>(other) ⇒ Object



72
73
74
75
76
77
78
79
80
# File 'opal/stdlib/bigdecimal.rb', line 72

def <=>(other)
  result = case other
           when self.class
             bignumber.JS.comparedTo(other.bignumber)
           when Number
             bignumber.JS.comparedTo(other)
           end
  `#{result} === null ? nil : #{result}`
end

#==(other) ⇒ Object Also known as: ===



59
60
61
62
63
64
65
66
67
68
# File 'opal/stdlib/bigdecimal.rb', line 59

def ==(other)
  case other
  when self.class
    bignumber.JS.equals(other.bignumber)
  when Number
    bignumber.JS.equals(other)
  else
    false
  end
end

#>(other) ⇒ Object



92
93
94
95
# File 'opal/stdlib/bigdecimal.rb', line 92

def >(other)
  return false if nan? || other && other.nan?
  super
end

#>=(other) ⇒ Object



97
98
99
100
# File 'opal/stdlib/bigdecimal.rb', line 97

def >=(other)
  return false if nan? || other && other.nan?
  super
end

#absObject



102
103
104
# File 'opal/stdlib/bigdecimal.rb', line 102

def abs
  self.class.new(bignumber.JS.abs)
end

#add(other, digits = 0) ⇒ Object Also known as: +



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'opal/stdlib/bigdecimal.rb', line 106

def add(other, digits = 0)
  if digits.nil?
    raise TypeError, 'wrong argument type nil (expected Fixnum)'
  end

  if digits < 0
    raise ArgumentError, 'argument must be positive'
  end

  other, _ = coerce(other)

  result = bignumber.JS.plus(other.bignumber)

  if digits > 0
    result = result.JS.toDigits(digits, self.class.mode(ROUND_MODE))
  end

  self.class.new(result)
end

#ceil(n = nil) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'opal/stdlib/bigdecimal.rb', line 128

def ceil(n = nil)
  unless bignumber.JS.isFinite
    raise FloatDomainError, "Computation results to 'Infinity'"
  end

  if n.nil?
    bignumber.JS.round(0, ROUND_CEILING).JS.toNumber
  elsif n >= 0
    self.class.new(bignumber.JS.round(n, ROUND_CEILING))
  else
    self.class.new(bignumber.JS.round(0, ROUND_CEILING))
  end
end

#coerce(other) ⇒ Object



142
143
144
145
146
147
148
149
150
151
# File 'opal/stdlib/bigdecimal.rb', line 142

def coerce(other)
  case other
  when self.class
    [other, self]
  when Number
    [self.class.new(other), self]
  else
    raise TypeError, "#{other.class} can't be coerced into #{self.class}"
  end
end

#div(other, digits = nil) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'opal/stdlib/bigdecimal.rb', line 153

def div(other, digits = nil)
  return self / other if digits == 0

  other, _ = coerce(other)

  if nan? || other.nan?
    raise FloatDomainError, "Computation results to 'NaN'(Not a Number)"
  end

  if digits.nil?
    if other.zero?
      raise ZeroDivisionError, 'divided by 0'
    end

    if infinite?
      raise FloatDomainError, "Computation results to 'Infinity'"
    end

    return self.class.new(bignumber.JS.dividedToIntegerBy(other.bignumber))
  end

  self.class.new(bignumber.JS.dividedBy(other.bignumber).JS.round(digits, self.class.mode(ROUND_MODE)))
end

#finite?Boolean

Returns:



177
178
179
# File 'opal/stdlib/bigdecimal.rb', line 177

def finite?
  bignumber.JS.isFinite
end

#infinite?Boolean

Returns:



181
182
183
184
# File 'opal/stdlib/bigdecimal.rb', line 181

def infinite?
  return nil if finite? || nan?
  bignumber.JS.isNegative ? -1 : 1
end

#minus(other) ⇒ Object Also known as: -



186
187
188
189
# File 'opal/stdlib/bigdecimal.rb', line 186

def minus(other)
  other, _ = coerce(other)
  self.class.new(bignumber.JS.minus(other.bignumber))
end

#mult(other, digits = nil) ⇒ Object Also known as: *



193
194
195
196
197
198
199
200
201
# File 'opal/stdlib/bigdecimal.rb', line 193

def mult(other, digits = nil)
  other, _ = coerce(other)

  if digits.nil?
    return self.class.new(bignumber.JS.times(other.bignumber))
  end

  self.class.new(bignumber.JS.times(other.bignumber).JS.round(digits, self.class.mode(ROUND_MODE)))
end

#nan?Boolean

Returns:



205
206
207
# File 'opal/stdlib/bigdecimal.rb', line 205

def nan?
  bignumber.JS.isNaN
end

#quo(other) ⇒ Object Also known as: /



209
210
211
212
# File 'opal/stdlib/bigdecimal.rb', line 209

def quo(other)
  other, _ = coerce(other)
  self.class.new(bignumber.JS.dividedBy(other.bignumber))
end

#signObject



216
217
218
219
220
221
222
223
# File 'opal/stdlib/bigdecimal.rb', line 216

def sign
  if bignumber.JS.isNaN
    return SIGN_NaN
  end
  if bignumber.JS.isZero
    return bignumber.JS.isNegative ? SIGN_NEGATIVE_ZERO : SIGN_POSITIVE_ZERO
  end
end

#sub(other, precision) ⇒ Object



225
226
227
228
# File 'opal/stdlib/bigdecimal.rb', line 225

def sub(other, precision)
  other, _ = coerce(other)
  self.class.new(bignumber.JS.minus(other.bignumber))
end

#to_dObject

call-seq: a.to_d -> bigdecimal

Returns self.

require 'bigdecimal/util'

d = BigDecimal("3.14")
d.to_d                       # => 0.314e1


106
107
108
# File 'opal/stdlib/bigdecimal/util.rb', line 106

def to_d
  self
end

#to_digitsObject

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/util'

d = BigDecimal("3.14")
d.to_digits                  # => "3.14"


86
87
88
89
90
91
92
93
94
# File 'opal/stdlib/bigdecimal/util.rb', line 86

def to_digits
  if nan? || infinite? || zero?
    to_s
  else
    i          = to_i.to_s
    _, f, _, z = frac.split
    i + '.' + ('0' * -z) + f
  end
end

#to_fObject



230
231
232
# File 'opal/stdlib/bigdecimal.rb', line 230

def to_f
  bignumber.JS.toNumber
end

#to_s(s = '') ⇒ Object



234
235
236
# File 'opal/stdlib/bigdecimal.rb', line 234

def to_s(s = '')
  bignumber.JS.toString
end

#zero?Boolean

Returns:



238
239
240
# File 'opal/stdlib/bigdecimal.rb', line 238

def zero?
  bignumber.JS.isZero
end