Temporary tag for this failure. Updated CI spec coming.
[rbx.git] / kernel / core / integer.rb
blob0f67ec898d2a78dd051ac5c3aa5fb5b761ed228d
1 # depends on: class.rb numeric.rb ctype.rb precision.rb
3 class Integer < Numeric
4   include CType
5   include Precision
7   def self.induced_from(obj)
8     case obj
9     when Fixnum, Bignum
10       obj
11     when Float
12       obj.to_i
13     else
14       raise TypeError, "failed to convert #{obj.class} into Integer"
15     end
16   end
18   def &(other)
19     self & Type.coerce_to(other, Integer, :to_int)
20   end
21    
22   def |(other)
23     self | Type.coerce_to(other, Integer, :to_int)
24   end
25   
26   def ^(other)
27     self ^ Type.coerce_to(other, Integer, :to_int)
28   end
30   def times
31     i = 0
32     while i < self
33       yield i
34       i += 1
35     end
36     self
37   end
38   
39   def upto(val)
40     i = self
41     while i <= val
42       yield i
43       i += 1
44     end
45     return self
46   end
47   
48   def downto(val)
49     i = self
50     while i >= val
51       yield i
52       i -= 1
53     end
54     return self
55   end
57   def to_i
58     self
59   end
60   alias_method :to_int, :to_i
61   alias_method :round, :to_i
62   alias_method :truncate, :to_i
64   def chr
65     raise RangeError.new("#{self} is out of the valid character range") if self > 255 || self < 0
66     String.template 1, self
67   end
68   
69   def [](index)
70     return 0 if index.is_a?(Bignum)
71     index = Type.coerce_to(index, Integer, :to_int)
72     index < 0 ? 0 : (self >> index) & 1
73   end
75   def **(exp)
76     if !exp.is_a?(Integer)
77       b, a = math_coerce(exp)
78       return a ** b
79     end
80     
81     return 1 if exp == 0
82     return self if exp == 1 || self == 0 || self == 1
83     return exp % 2 == 0 ? 1 : -1 if self == -1
84     
85     if exp < 0
86       Float(self) ** Float(exp)
87     else
88       out = 1
89       base = self
90       while exp > 0
91         if (exp & 1) != 0
92           out *= base
93           exp -= 1
94         else
95           base *= base
96           exp >>= 1
97         end
98       end
99       out
100     end
101   end
103   def next
104     self + 1
105   end
106   alias_method :succ, :next
108   def integer?
109     true
110   end
112   ##
113   # Returns the minimum number of bits required for integer in (signed int)
114   # binary format
115   #--
116   # NOTE: rshift would probably be slightly more efficient but since i'm
117   # probably going to use this to simplify the complex behavior of
118   # ruby's << and >> it would defeat the purpose by creating a circular
119   # dependency.
120   #
121   # TODO: convert algorithm to primitive so no circular dependency?
122   #++
124   def bits(int = self)
125     if int.zero?
126       1 # sign bit storage
127     elsif int > 0
128       bits(int / 2) + 1 # could use >> in primitive
129     else
130       bits(~int / 2) + 1 # could use >> in primitive
131     end
132   end