Temporary tag for this failure. Updated CI spec coming.
[rbx.git] / kernel / core / float.rb
blob6dbfacc29fba096220fea570bc28952a94fc0893
1 # depends on: numeric.rb precision.rb class.rb
3 class Float < Numeric
5   include Precision
7   RADIX      = Platform::Float.RADIX
8   ROUNDS     = Platform::Float.ROUNDS
9   MIN        = Platform::Float.MIN
10   MAX        = Platform::Float.MAX
11   MIN_EXP    = Platform::Float.MIN_EXP
12   MAX_EXP    = Platform::Float.MAX_EXP
13   MIN_10_EXP = Platform::Float.MIN_10_EXP
14   MAX_10_EXP = Platform::Float.MAX_10_EXP
15   DIG        = Platform::Float.DIG
16   MANT_DIG   = Platform::Float.MANT_DIG
17   EPSILON    = Platform::Float.EPSILON
18   STRLEN     = 32
19   
20   def self.induced_from(obj)
21     case obj
22     when Float, Bignum, Fixnum
23       obj.to_f
24     else
25       raise TypeError, "failed to convert #{obj.class} into Float"
26     end
27   end
28   
29   def coerce(other)
30     return [other, self] if other.__kind_of__ Float
31     [Float(other), self]
32   end
33   
34   def -@
35     Ruby.primitive :float_uminus
36   end
38   def +(other)
39     Ruby.primitive :float_add
40     b, a = math_coerce other
41     a + b
42   end
43   
44   def -(other)
45     Ruby.primitive :float_sub
46     b, a = math_coerce other
47     a - b
48   end
49   
50   def *(other)
51     Ruby.primitive :float_mul
52     b, a = math_coerce other
53     a * b
54   end
55   
56   #--
57   # see README-DEVELOPERS regarding safe math compiler plugin
58   #++
60   def divide(other)
61     Ruby.primitive :float_div
62     b, a = math_coerce other
63     a.divide b
64   end
65   alias_method :/, :divide
66   alias_method :quo, :/
68   def divmod(other)
69     Ruby.primitive :float_divmod
70     b, a = math_coerce other
71     a.divmod b
72   end
74   def **(other)
75     Ruby.primitive :float_pow
76     b, a = math_coerce other
77     a ** b
78   end
80   def %(other)
81     return 0 / 0.to_f if other == 0
82     self.divmod(Float(other))[1]
83   end
84   alias_method :modulo, :%
86   def <(other)
87     Ruby.primitive :float_lt
88     b, a = math_coerce other, :compare_error
89     a < b
90   end
91   
92   def <=(other)
93     Ruby.primitive :float_le
94     b, a = math_coerce other, :compare_error
95     a <= b
96   end
97   
98   def >(other)
99     Ruby.primitive :float_gt
100     b, a = math_coerce other, :compare_error
101     a > b
102   end
103   
104   def >=(other)
105     Ruby.primitive :float_ge
106     b, a = math_coerce other, :compare_error
107     a >= b
108   end
109   
110   def <=>(other)
111     Ruby.primitive :float_compare
112     b, a = math_coerce other, :compare_error
113     a <=> b
114   end
116   def ==(other)
117     Ruby.primitive :float_equal
118     begin
119       b, a = math_coerce(other)
120       return a == b
121     rescue TypeError
122       return other == self
123     end
124   end
126   def eql?(other)
127     Ruby.primitive :float_eql
128   end
129   
130   def nan?
131     Ruby.primitive :float_isnan
132   end
134   def infinite?
135     Ruby.primitive :float_isinf
136   end
137   
138   def finite?
139     not (nan? or infinite?) 
140   end
142   def to_f
143     self
144   end
145   
146   def to_i
147     Ruby.primitive :float_to_i
148   end
149   alias_method :to_int, :to_i
150   alias_method :truncate, :to_i
151   
152   def to_s
153     return (self < 0 ? "-Infinity" : "Infinity") if infinite?
154     return "NaN" if nan?
155     
156     str = Platform::Float.to_s_formatted STRLEN, "%#.15g", self
157     e = str.index('e') || str.size
158     unless str[e-1].isdigit
159       str = Platform::Float.to_s_formatted STRLEN, "%#.14e", self
160       e = str.index('e') || str.size
161     end
162     str.gsub(/(\.\d+?)(0+)($|e[+-]\d*)/, '\1\3')
163   end
164   alias_method :inspect, :to_s
166   def to_s_formatted(fmt)
167     Platform::Float.to_s_formatted STRLEN, fmt, self
168   end
169   private :to_s_formatted
170   
171   def round
172     Ruby.primitive :float_round
173   end