class SatoshiProc

Constants

UNIT_DENOMINATIONS

Says how many digits after the decimal point a denomination has.

Attributes

from_unit[R]
to_unit[R]
value[R]

Public Class Methods

new(n=nil, from_unit: 'proc', to_unit: 'proc', unit: nil) click to toggle source
# File lib/satoshiproc.rb, line 16
def initialize(n=nil, from_unit: 'proc', to_unit: 'proc', unit: nil)
  n = 0 if n.nil?
  if unit
    @from_unit = @to_unit = unit.downcase.to_sym
  else
    @from_unit = from_unit.downcase.to_sym
    @to_unit   = to_unit.downcase.to_sym
  end
  @value = convert_to_satoshiproc(n) if n
end

Public Instance Methods

*(i) click to toggle source

IMPORTANT: multiplication is done on satoshiprocs, not proc. 0.01*0.02 PROC will be a larger value.

# File lib/satoshiproc.rb, line 96
def *(i)
  if i.kind_of?(SatoshiProc)
    SatoshiProc.new(self.to_i * i, from_unit: :satoshiproc)
  else
    self.to_i * i
  end
end
+(i) click to toggle source
# File lib/satoshiproc.rb, line 78
def +(i)
  if i.kind_of?(SatoshiProc)
    SatoshiProc.new(self.to_i + i, from_unit: :satoshiproc)
  else
    self.to_i + i
  end
end
-(i) click to toggle source
# File lib/satoshiproc.rb, line 86
def -(i)
  if i.kind_of?(SatoshiProc)
    SatoshiProc.new(self.to_i - i, from_unit: :satoshiproc)
  else
    self.to_i - i
  end
end
<(i) click to toggle source
# File lib/satoshiproc.rb, line 62
def <(i)
  self.to_i < i
end
<=(i) click to toggle source
# File lib/satoshiproc.rb, line 70
def <=(i)
  self.to_i <= i
end
==(i) click to toggle source
# File lib/satoshiproc.rb, line 74
def ==(i)
  self.to_i == i
end
>(i) click to toggle source
# File lib/satoshiproc.rb, line 58
def >(i)
  self.to_i > i
end
>=(i) click to toggle source
# File lib/satoshiproc.rb, line 66
def >=(i)
  self.to_i >= i
end
coerce(other) click to toggle source
# File lib/satoshiproc.rb, line 104
def coerce(other)
  if other.kind_of?(Integer)
    [other, self.to_i]
  else
    raise TypeError, message: "SatoshiProc cannot be coerced into anything but Integer"
  end
end
satoshiproc_value()
Alias for: to_i
satoshiproc_value=(v) click to toggle source
# File lib/satoshiproc.rb, line 54
def satoshiproc_value=(v)
  @value = v
end
to_i() click to toggle source
# File lib/satoshiproc.rb, line 39
def to_i
  return 0 if @value.nil?
  @value
end
Also aliased as: satoshiproc_value
to_mproc(as: :number) click to toggle source
# File lib/satoshiproc.rb, line 31
def to_mproc(as: :number)
  to_denomination(UNIT_DENOMINATIONS[:mproc], as: as)
end
to_proc(as: :number) click to toggle source
# File lib/satoshiproc.rb, line 27
def to_proc(as: :number)
  to_denomination(UNIT_DENOMINATIONS[:proc], as: as)
end
to_s() click to toggle source
# File lib/satoshiproc.rb, line 45
def to_s
  to_unit.to_s
end
value=(n) click to toggle source
# File lib/satoshiproc.rb, line 49
def value=(n)
  n = 0 if n.nil?
  @value = convert_to_satoshiproc(n)
end

Private Instance Methods

convert_to_satoshiproc(n) click to toggle source
# File lib/satoshiproc.rb, line 136
def convert_to_satoshiproc(n)
  n = BigDecimal.new(n.to_s)

  decimal_part_length = n.to_s("F").split(".")[1]
  decimal_part_length = if decimal_part_length
    decimal_part_length.sub(/0*\Z/, "").length
  else
    0
  end

  if decimal_part_length > UNIT_DENOMINATIONS[@from_unit]
    raise TooManyDigitsAfterDecimalPoint,
      "Too many digits (#{decimal_part_length}) after decimal point used for #{@from_unit} value, while #{UNIT_DENOMINATIONS[@from_unit]} allowed" 
  end

  n = ("%.#{UNIT_DENOMINATIONS[@from_unit]}f" % n) # otherwise we might see a scientific notation
  n = n.split('.')
  n[1] ||= '' # in the case where there's no decimal part
  n[1] += "0"*(UNIT_DENOMINATIONS[@from_unit]-n[1].length) if n[1]

  if(n.join.to_i > 21_000_000_00000000)
    raise TooLarge, "Max value for Proc is 21 million PROC"
  end

  n.join.to_i

end
to_denomination(digits_after_delimiter, as: :number) click to toggle source
# File lib/satoshiproc.rb, line 114
def to_denomination(digits_after_delimiter, as: :number)
  sign  = @value < 0 ? -1 : 1
  val   = @value.abs
  return val if digits_after_delimiter <= 0
  leading_zeros = "0"*(18-val.to_s.length)
  result = leading_zeros + val.to_s
  result.reverse!
  result = result.slice(0..digits_after_delimiter-1) + '.' + result.slice(digits_after_delimiter..17)
  result.reverse!
  result = result.sub(/\A0*/, '').sub(/0*\Z/, '') # remove zeros on both sides
  if as == :number
    result.to_f*sign 
  else
    if result == '.'
      result = '0.0'
    elsif result =~ /\A\./
      result = "0#{result}"
    end
    sign == -1 ? "-#{result}" : result
  end
end