Module: Lexidecimal

Defined in:
lib/lexidecimal.rb

Constant Summary collapse

MINUS =
'-'.freeze
PLUS =
'p'.freeze

Class Method Summary collapse

Class Method Details

.decimal_to_string(num) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/lexidecimal.rb', line 36

def self.decimal_to_string num
  sign, digits, base, exponent = num.split
  
  return '0' if digits == '0'
  
  negative = (sign < 1)
  if negative
    digits = self.invert digits
    sign = MINUS
    antisign = PLUS
  else
    sign = PLUS
    antisign = MINUS
  end
  
  "#{sign}#{self.int_to_string(negative ? -exponent : exponent)}#{digits}#{antisign}"
end

.enum_to_decimal(enum) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/lexidecimal.rb', line 85

def self.enum_to_decimal enum
  sign = enum.next
  negative = (sign == MINUS)
  antisign = (negative ? PLUS : MINUS)
  
  exponent = self.enum_to_int enum
  exponent = -exponent if negative
  
  digits = ''
  
  while (cur = enum.next) != antisign
    if negative
      digits << (9 - cur.to_i).to_s
    else
      digits << cur
    end
  end
  
  BigDecimal.new "#{negative ? '-' : ''}0.#{digits}e#{exponent}"
end

.enum_to_int(enum) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/lexidecimal.rb', line 58

def self.enum_to_int enum
  sign = enum.next
  return 0 if sign == '0'
  count = 0
  while (cur = enum.next) == sign
    count += 1
  end
  negative = (sign == MINUS)
  length = cur.to_i
  length = 9 - length if negative
  count.times do
    new_length = 0
    length.times do
      new_length *= 10
      digit = enum.next.to_i
      digit = 9 - digit if negative
      new_length += digit
    end
    length = new_length
  end
  negative ? -length : length
end

.int_to_string(num, sign = nil, negative = nil) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/lexidecimal.rb', line 11

def self.int_to_string num, sign=nil, negative=nil
  return '0' if num == 0
  
  if sign.nil?
    if num < 0
      sign = MINUS
      negative = true
      num = -num
    else
      sign = PLUS
      negative = false
    end
  end
  
  string = num.to_s
  string = self.invert string if negative
  
  length = string.length
  if length > 1
    "#{sign}#{self.int_to_string length, sign, negative}#{string}"
  else
    "#{sign}#{string}"
  end
end

.invert(string) ⇒ Object



7
8
9
# File 'lib/lexidecimal.rb', line 7

def self.invert string
  string.each_char.map{|d| 9-d.to_i}.join
end

.string_to_decimal(string) ⇒ Object



81
82
83
# File 'lib/lexidecimal.rb', line 81

def self.string_to_decimal string
  self.enum_to_decimal string.each_char
end

.string_to_int(string) ⇒ Object



54
55
56
# File 'lib/lexidecimal.rb', line 54

def self.string_to_int string
  self.enum_to_int string.each_char
end