-
Notifications
You must be signed in to change notification settings - Fork 0
/
arithmatic.js
361 lines (300 loc) · 11.6 KB
/
arithmatic.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
89
90
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
class InfiniteNumberArithmatic {
/** An internal member Array to contain the digits of the Infinite Integer.
* @private
* @type {Array<Number>}
*/
_internalArray = []
constructor(inputObject) {
if (typeof (inputObject) === "number") {
// check if Number is not a NaN
if (isNaN(inputObject)) {
throw new Error("Input is NaN.")
}
// check for negative values
if (inputObject < 0) {
throw new Error("Input cannot be negative")
}
// check for integral values only
if ((inputObject % 1) != 0) {
throw new Error("Input needs to be an integral value.")
}
while (inputObject != 0) {
this._internalArray.unshift(inputObject % 10)
inputObject = Math.floor(inputObject / 10)
}
} else if (typeof (inputObject) === "string") {
// check if length is not zero
if (inputObject.length == 0) {
throw new Error("Empty string is not accepted.")
}
// check if every character is a decimal digit
let myRegex = /^[0-9]+$/
if (!myRegex.test(inputObject)) {
throw new Error("String can have decimal numbers only.")
}
for (let index = 0; index < inputObject.length; index++) {
const currentDigit = parseInt(inputObject.charAt(index))
this._internalArray.push(currentDigit)
}
}
else if (Array.isArray(inputObject)) { // IS THIS HOW ITS DONE?
// TODO validate the individual elements of the inputArray and initialize
for(let i=0 ;i<inputObject.length-1;i++){
if( !Number.isInteger(inputObject[i]) ){
throw new Error('All array members must be integers')
}
}
// the _internalArray
// initialize the member array
this._internalArray = inputObject
} else if (typeof inputObject === "object") {
console.log("You sent an Object")
// TODO check if this object has getInternalArray() and make a deep copy
if(typeof(inputObject.getInternalArray())==InfiniteNumberArithmatic){
// and assign it to local _internalArray
this._internalArray=inputObject.getInternalArray();
// initialize the member array
}else{
throw new Error('The object must be from class InfiniteNumberArithmetic');
}
} else {
console.log("Invalid data!")
throw new Error(`Constuctor of IniniteNumber does not support this data`
+ ` type ${typeof inputObject}`)
}
}
/** Helper method to return the _internalArray variable which contains the
* Inifnite precision Integer.
* @returns {Array<Number>} the internal array representing individual digits
*/
getInternalArray() {
// TODO,
var temp = new Array()
temp = this._internalArray
return temp
}
/** Helper method to return the representation of this Infinite Precision
*
*/
getNumberAsString() {
return this._internalArray.join('')
}
getaddition(obj){
let result = [];
let carry = 0;
let i = 0;
let firstNumber = this._internalArray;
let secondNumber = obj.getInternalArray(); // Use getInternalArray without parameters
firstNumber = firstNumber.reverse();
secondNumber = secondNumber.reverse();
/**
* the below loop will run for the number of times until length of both
* the array have digits to add
*/
for( i;i<=firstNumber.length-1 && i <=secondNumber.length-1;i++){
//when the carry is generated
if(firstNumber[i]+secondNumber[i]+carry>9){
//to push the units digit in the result
result.push((firstNumber[i]+secondNumber[i]+carry)%10)
//to add the carry in the next addition
carry = Math.floor((firstNumber[i]+secondNumber[i]+carry)/10)
}else{
//when the carry is not generated directly add the sum in the result
result.push(firstNumber[i]+secondNumber[i]+carry)
carry = 0
}
// console.log(result)
}
/**
* if firstnumber is longer in length
*/
if(firstNumber.length-i){
for(i;i<=firstNumber.length-1;i++){
if(firstNumber[i]+carry>9){
//to push the units digit in the result
result.push((firstNumber[i]+carry)%10)
//to add the carry in the next addition
carry = Math.floor((firstNumber[i]+carry)/10)
}else{
//when the carry is not generated directly add the sum in the result
result.push(firstNumber[i]+carry)
carry = 0
}
}
}
/**
* if second numeber is larger in length
*/
if(secondNumber.length-i){
for(i;i<=secondNumber.length-1;i++){
if(secondNumber[i]+carry>9){
//to push the units digit in the result
result.push((secondNumber[i]+carry)%10)
//to add the carry in the next addition
carry = Math.floor((secondNumber[i]+carry)/10)
}else{
//when the carry is not generated directly add the sum in the result
result.push(secondNumber[i]+carry)
carry = 0
}
}
}
if(carry!=0) {
result.push(carry)
}
return result.reverse()
}
getsubtraction(obj){
let ans = [];
let biggerNumber;
let smallerNumber;
let first = this._internalArray;
let second = obj.getInternalArray();
// checking which numeber bigger
if(first.length > second.length){
biggerNumber = first
smallerNumber = second
}else if(first.length == second.length){
//Comparing each digit to find the bigger number
for(let i=0;i<first.length;i++){
//if any one digit of first number becomes larger than the
//digit at same place in second numeber, the first number becomes
//the bigger number
if(first[i]>second[i]){
biggerNumber = first
smallerNumber = second
break
}
if(second[i]>first[i]){
biggerNumber = second
smallerNumber = first
break
}
}
}else {
//condition where the second number is larger than the first number
biggerNumber = second
smallerNumber = first
}
//revrse the smaller number add trailing to add zeros at the end
smallerNumber = smallerNumber.reverse()
//add trailing zeros until it's length equal to the bigger number
while(smallerNumber.length<biggerNumber.length){
smallerNumber.push(0)
}
//return the smaller number to its original number
smallerNumber=smallerNumber.reverse()
//subtracting each digit of smaller number from bigger number
for(let i=biggerNumber.length-1;i>=0;i--){
//check if borrow if needed or not
if(biggerNumber[i]-smallerNumber[i]>=0){
//if not needed simply push the difference of digits
ans.push(biggerNumber[i]-smallerNumber[i])
}else{
//if borrow is needed
//add 10 to current digit
biggerNumber[i] = biggerNumber[i]+10
// subtract 1 from previous number
biggerNumber[i-1] = biggerNumber[i-1] - 1
//perform the subtraction of digits
ans.push(biggerNumber[i]-smallerNumber[i])
}
}
return ans.reverse()
}
/**subFuntion to multiply one number with entire array
* @private
* @param {Number} num to be multiplied
* @param {Array<Number>} numArray to be multiplied
* @return {Array} Array after multiplication
*/
multiplyWithNumber(numArray, num, initialZero) {
let ans = [];
let carry = 0;
//to append initial zero for final calculation
for (let zeroCount = 0; zeroCount < initialZero; zeroCount++) {
ans.unshift(0);
}
for (let numIndex = numArray.length - 1; numIndex >= 0; numIndex--) {
let temp = (numArray[numIndex] * num) + carry;
ans.unshift(temp%10);
carry = Math.floor(temp/10);
}
if(carry!==0) ans.unshift(carry)
return ans;
}
/**Function to return the multiplication of two Arrays
* @param {Array<Number>} numToMultiply input array should be number
* @throws {Error} if numToMultiply is not valid object
* @return {Array} result array of Multiplication
*/
getmultiplication(numToMultiply) {
console.log(numToMultiply instanceof InfiniteNumberArithmatic)
//check if the input is valid
if(!(numToMultiply instanceof InfiniteNumberArithmatic)){
throw new Error("given input is not an object")
}
let num1=this._internalArray
let num2=numToMultiply._internalArray;
//initialize the ans as object
let ans = new InfiniteNumberArithmatic(0);
//multiply entire num1 array with elemetents of num2 array one by one
// then add it to the ans
let num2Index = (num2.length - 1)
for (; num2Index >= 0; num2Index--) {
// initial zeros to be added
let initialZero = (num2.length - 1) - num2Index;
// multiply num1 with single digit of num2 and store into sample
let sample= this.multiplyWithNumber(num1,num2[num2Index],initialZero);
//convert sample into infiniteNumber object
sample= new InfiniteNumberArithmatic(sample.join(""))
// add the ans object with sample object and convert ans again into object
ans=ans.getaddition(sample)
ans = new InfiniteNumberArithmatic(ans.join(""));
}
return ans;
}
divide(obj){
//some features are yet to be added
let biggerNumber;
let smallerNumber;
let first = this._internalArray;
let second = obj.getInternalArray();
// checking which numeber bigger
if(first.length > second.length){
biggerNumber = first
smallerNumber = second
}else if(first.length == second.length){
//Comparing each digit to find the bigger number
for(let i=0;i<first.length;i++){
//if any one digit of first number becomes larger than the
//digit at same place in second numeber, the first number becomes
//the bigger number
if(first[i]>second[i]){
biggerNumber = first
smallerNumber = second
break
}
if(second[i]>first[i]){
biggerNumber = second
smallerNumber = first
break
}
}
}else {
//condition where the second number is larger than the first number
biggerNumber = second
smallerNumber = first
}
}
}
function testing(){
let obj1 = new InfiniteNumberArithmatic(68568526)
let obj2 = new InfiniteNumberArithmatic(94646466)
let obj3 = new InfiniteNumberArithmatic(obj1.getaddition(obj2))
console.log("Addition : ",obj3.getNumberAsString())
let obj4 = new InfiniteNumberArithmatic(obj2.getsubtraction(obj1))
console.log("Subtraction : ",obj4.getNumberAsString())
// let obj5 = new InfiniteNumberArithmatic(obj1.getmultiplication(obj2))
}
testing()