UNPKG

3.23 kBJavaScriptView Raw
1void function(root){
2 "use strict"
3
4 var numbers = {}
5 , u = require('totemizer')
6 , boo = require('boo')
7 , rational
8 , apply = u.liberate(Function.prototype.apply)
9 ;
10
11
12 function checkInput(input){ return (input && input.init === rational.init) ? input : rat(input) }
13
14 function gcd(a, b){
15 var t;
16 a = Math.abs(a)
17 b = Math.abs(b)
18 while (b > 0) {
19 t = b
20 b = a % b
21 a = t
22 }
23 return a
24 }
25
26 function lcm(a, b){ return Math.abs(a*b)/gcd(a,b) }
27
28 function hashify(r){ return r[0]+'/'+r[1] }
29
30 function display(r){ return ''+r[0]+(r[1]!=1?'/'+r[1]:'') }
31
32 function val(r){ return r[0]/r[1] }
33
34 function add(x, y){ return rat(x[0]*y[1]+y[0]*x[1], x[1]*y[1]) }
35
36 function subtract(x, y){ return rat(x[0]*y[1]-y[0]*x[1], x[1]*y[1]) }
37
38 function multiply(x, y){ return rat(x[0]*y[0], x[1]*y[1]) }
39
40 function divide(x, y){ return rat(x[0]*y[1], y[0]*x[1]) }
41
42 rational = boo.Base.derive({
43 init : function(numerator, denominator){
44 this[0] = numerator
45 this[1] = denominator
46 }
47 , toString : u.enslave(hashify)
48 , display : u.enslave(display)
49
50 , val : u.enslave(val)
51
52 , add : u.enslave(add)
53 , plus : u.enslave(add)
54
55 , subtract : u.enslave(subtract)
56 , minus : u.enslave(subtract)
57 , sub: u.enslave(subtract)
58
59 , multiply : u.enslave(multiply)
60 , times : u.enslave(multiply)
61 , mul: u.enslave(multiply)
62
63 , divide : u.enslave(divide)
64 , per : u.enslave(divide)
65 , div: u.enslave(divide)
66
67 })
68
69 function rat(numerator, denominator){
70
71 var index, divisor;
72
73 if ( ! u.isInt(numerator) ) {
74 throw new Error('invalid argument '+numerator+' ('+(typeof numerator)+')')
75 } else if ( typeof numerator === 'string' ) {
76 numerator = Number(numerator)
77 }
78
79 if ( ! u.isInt(denominator) ) {
80 denominator = 1
81 } else if ( typeof denominator === 'string' ) {
82 denominator = Number(denominator)
83 }
84
85 if ( denominator === 0 ) {
86
87 if ( numerator !== 0 ) numerator = 1
88
89 } else {
90
91 divisor = gcd(numerator, denominator)
92 if ( Math.abs(divisor) > 1 ) {
93 numerator = numerator / divisor
94 denominator = denominator / divisor
95 }
96
97 if ( denominator < 0 ) {
98 numerator *= -1
99 denominator *= -1
100 }
101 }
102
103 index = hashify([numerator, denominator])
104
105 if ( numbers[index] === undefined ) {
106 numbers[index] = rational.make(numerator, denominator)
107 }
108
109 return numbers[index]
110
111 }
112
113 rat.checkInput = checkInput
114 rat.gcd = function(a, b){ return rat(gcd(a[0],b[0]), lcm(a[1],b[1])) }
115 rat.lcm = function(a, b){ return rat(lcm(a[0],b[0]), gcd(a[1],b[1])) }
116 rat.add = add
117 rat.div = divide
118 rat.sub = subtract
119 rat.mul = multiply
120
121 if ( typeof module !== 'undefined' && module.exports ) {
122 module.exports = rat
123 } else {
124 root.factory = rat
125 }
126
127}(this)