345215505446a03e83a0ba5b380facfaaba10376
[nit.git] / lib / standard / numeric.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2013-2014 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Advanced services for `Numeric` types
18 module numeric
19
20 import math
21 import string
22
23 redef class Text
24 # Get the numeric version of `self`
25 #
26 # require: `is_numeric`
27 #
28 # ~~~~
29 # assert "0".to_n == 0
30 # assert "0.0".to_n == 0.0
31 # assert ".12345".to_n == 0.12345
32 # assert "12345".to_n == 12345
33 # ~~~~
34 fun to_n: Numeric
35 do
36 if chars.has('.') then return to_f
37 return to_i
38 end
39 end
40
41 redef interface Numeric
42 # Universal `+` with any `Numeric`
43 #
44 # ~~~~
45 # assert 1.add(1) == 2
46 # assert 1.add(0.1) == 1.1
47 # assert 1.1.add(1.1) == 2.2
48 # assert 1.1.add(1) == 2.1
49 # ~~~~
50 fun add(other: Numeric): Numeric is abstract
51
52 # Universal `-` with any `Numeric`
53 #
54 # ~~~~
55 # assert 2.sub(1) == 1
56 # assert 1.sub(0.1) == 0.9
57 # assert 1.1.sub(0.1) == 1.0
58 # assert 2.1.sub(1) == 1.1
59 # ~~~~
60 fun sub(other: Numeric): Numeric is abstract
61
62 # Universal `/` with any `Numeric`
63 #
64 # ~~~~
65 # assert 8.div(2) == 4
66 # assert 4.div(0.5) == 8.0
67 # assert 1.1.div(0.1) == 11.0
68 # assert 2.2.div(2) == 1.1
69 # ~~~~
70 fun div(other: Numeric): Numeric is abstract
71
72 # Universal `*` with any `Numeric`
73 #
74 # ~~~~
75 # assert 2.mul(4) == 8
76 # assert 11.mul(0.1) == 1.1
77 # assert 11.1.mul(0.1) == 1.11
78 # assert 1.1.mul(4) == 4.4
79 # ~~~~
80 fun mul(other: Numeric): Numeric is abstract
81 end
82
83 redef universal Int
84 redef fun add(other)
85 do
86 if other isa Float then
87 return to_f + other
88 else
89 return self + other.as(Int)
90 end
91 end
92
93 redef fun sub(other)
94 do
95 if other isa Float then
96 return to_f - other
97 else
98 return self - other.as(Int)
99 end
100 end
101
102 redef fun mul(other)
103 do
104 if other isa Float then
105 return to_f * other
106 else
107 return self * other.as(Int)
108 end
109 end
110
111 redef fun div(other)
112 do
113 if other isa Float then
114 return to_f / other
115 else if other isa Int then
116 if other == 0 then return self.to_f / 0.0
117 return self / other
118 else abort
119 end
120 end
121
122 redef universal Float
123 redef fun add(other) do return self + other.to_f
124 redef fun sub(other) do return self - other.to_f
125 redef fun div(other) do return self / other.to_f
126 redef fun mul(other) do return self * other.to_f
127 end