Class: Rational

Inherits:
Object
  • Object
show all
Defined in:
lib/include/rational.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.oneObject



2
3
4
# File 'lib/include/rational.rb', line 2

def self.one
  return Rational(1, 1)
end

.zeroObject



6
7
8
# File 'lib/include/rational.rb', line 6

def self.zero
  return Rational(0, 1)
end

Instance Method Details

#inverseObject



10
11
12
# File 'lib/include/rational.rb', line 10

def inverse
  return 1 / self
end

#to_ds(length = 64, base = 10) ⇒ Object

to decimal string

Raises:

  • (ArgumentError)


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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/include/rational.rb', line 91

def to_ds(length = 64, base = 10)
  raise ArgumentError, "invalid radix #{base}" if base < 2 or 36 < base

  # initialize

  quotient = []

  n = numerator.to_s(base).split('').map(&:to_i)
  exp = 0
  while 0 == n.last
    n.pop
    exp += 1
  end
  d = denominator
  loop do
    q, r = d.divmod(base)
    break unless 0 == r
    d = q
    exp -= 1
  end
  t = n[0]

  # division loop

  i = 1
  s = nil
  loop do
    q, r = t.divmod(d)
    t = r * base + n[i].to_i

    s = i - 1 if nil == s and q != 0
    quotient.push([q, nil])

    unless n[i]
      if 0 == t
        quotient.last[1] = 0
        break
      end
      break if s and i - s == length
      quotient.last[1] = t
    end

    i += 1
  end

  # format

  zero_count = 0
  while 0 == quotient[0][0]
    zero_count += 1
    if t == quotient.shift[1]
      # rotate 0

      while 0 == quotient[0][0]
        quotient.push(quotient.shift)
        zero_count += 1
      end
      break
    end
  end
  exp += n.size - zero_count

  convert = "0123456789abcdefghijklmnopqrstuvwxyz"
  rslt = "0." + quotient.map{|q| convert[q[0]]}.inject(&:+)
  rslt +=  "e" + exp.to_s unless 0 == exp

  return rslt
end

#to_rds(base = 10) ⇒ Object

to repeating decimal string

Raises:

  • (ArgumentError)


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
# File 'lib/include/rational.rb', line 15

def to_rds(base = 10)
  raise ArgumentError, "invalid radix #{base}" if base < 2 or 36 < base

  # initialize

  quotient = []

  n = numerator.to_s(base).split('').map(&:to_i)
  exp = 0
  while 0 == n.last
    n.pop
    exp += 1
  end
  d = denominator
  loop do
    q, r = d.divmod(base)
    break unless 0 == r
    d = q
    exp -= 1
  end
  t = n[0]

  # division loop

  i = 1
  loop do
    q, r = t.divmod(d)
    t = r * base + n[i].to_i

    quotient.push([q, nil])

    unless n[i]
      if 0 == t
        quotient.last[1] = 0
        break
      end
      break if quotient.map(&:last).include?(t)
      quotient.last[1] = t
    end

    i += 1
  end

  # format

  rslt = "0."

  zero_count = 0
  while 0 == quotient[0][0]
    zero_count += 1
    if t == quotient.shift[1]
      rslt += '('

      # rotate 0

      while 0 == quotient[0][0]
        quotient.push(quotient.shift)
        zero_count += 1
      end
      break
    end
  end
  exp += n.size - zero_count

  convert = "0123456789abcdefghijklmnopqrstuvwxyz"
  if 0 == quotient.last[1]
    rslt += quotient.map{|q| convert[q[0]]}.inject(&:+)
  else
    quotient.each do |q|
      rslt += convert[q[0]]
      rslt += '(' if t == q[1]
    end
    rslt +=  ")"
  end
  rslt +=  "e" + exp.to_s unless 0 == exp

  return rslt
end