AdolfJames Urian
AdolfJames Urian

Reputation: 95

My replace method is messing up in formatting numbers (adding commas to nums)

Everything is good until it comes to 6,555,444,333,222,111 or lets say quadrillion, after I added one more number (any number) it became 65,554,443,332,220 (for example the number is 5, it will be automatically 0, i.e any number from will replaced by 0) Because I'm making a calculator and so If it is 6 quadrillion and I press button 2 for examlple the last value should be 2, but its showing 0.

Heres my code:

        Number.prototype.formattedNumber = function() {
            this.Number = String(this).split('\.'); //Split '.' So it doesnt affect decimals
            if(this.Number.length > 1) {
                this.first = this.Number[0];
                this.second = this.Number[1];
                this.Number = this.first.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,') + '.' + this.second;
                return this.Number;
            }else{
                this.first = this.Number[0];
                this.Number = this.first.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
                console.log(this.Number);
                return this.Number;
            }
        }
        function print(button) {
        
            lastChild = lastIndex(expression);
            
            //This makes the default change only if length is 1
            if((expression[lastChild] === def || expression[lastChild] === def) && this.obj.innerHTML != oper.a && this.obj.innerHTML != oper.s && this.obj.innerHTML != oper.m && this.obj.innerHTML != oper.d && this.obj.id != 'decimal') {
                //Doesnt accept 0 at first number
                if(this.obj.innerHTML == def) {
                    return;
                }
                
                expression[lastChild] = this.obj.innerHTML;
                history.innerHTML = this.obj.innerHTML;
            }
            //This makes the operator so that to avoid spamming operators
            else if((expression[lastChild] === oper.a || expression[lastChild] === oper.s || expression[lastChild] === oper.m || expression[lastChild] === oper.d) && button === 'oper') {
                expression[lastChild] = this.obj.innerHTML;
                history.innerHTML = expression.join('');
            }
            //Default
            else{
                //replaces the previous expression to 'Ans'
                if(isAns) {
                    expression = [];
                    expression.push('Ans');
                    history.innerHTML = 'Ans';
                    isAns = false;
                }
                
                if(button === 'num') {
                    //handles error
                    if(expression[lastChild] === undefined || expression[lastChild] === null || expression[lastChild] === 'Ans') {
                        return;
                    }
                    
                    let even_odd = expression.length % 2;
                    let value = 0;
                    //even means to add value
                    if(even_odd === 1) {
                        expression[lastChild] += this.obj.innerHTML;
                        
                        value = parseFloat(expression[lastChild].split(',').join(''));
                        value = value.formattedNumber();
                        expression[lastChild] = value;
                        
                        history.innerHTML = expression.join('');
                    }
                    //odd means to append another value on array
                    else if(even_odd === 0) {
                        expression.push(this.obj.innerHTML);
                        history.innerHTML += this.obj.innerHTML;
                    }
                }else if(button === 'oper') {
                    if(expression[lastChild] === oper.a || expression[lastChild] === oper.s || expression[lastChild] === oper.m || expression[lastChild] === oper.d){
                        expression[lastchild] = this.obj.innerHTML;
                        history.innerHTML = this.obj.innerHTML;
                    }else{
                        expression.push(this.obj.innerHTML);
                        history.innerHTML += this.obj.innerHTML;
                    }
                }
            }
            
        }

//more codes....

Is there anyway to fix this?

Upvotes: 1

Views: 47

Answers (1)

Gian Singh Sarao
Gian Singh Sarao

Reputation: 71

If by add one more number you mean one more digit, then it is because you exceeded the max safe integer value of javascript. See this page on MDN for more info.

A number in the quadrillions which you gave as an example: 6,555,444,333,222,111

The max safe integer value of javascript: 9,007,199,254,740,991

Both next to each other:

6,555,444,333,222,111
9,007,199,254,740,991

Adding another digit to the example would make it an order of magnitude bigger than the max integer value, and because javascript doesn't know what to do with this it ends up losing some accuracy.

You should check the number of digits inputted, and if its bigger than 16, use BigInt. You also might need to redo some work in other parts of your code, for example parseFloat loses accuracy when working with BigInt because it tries to convert BigInt to Number.

Upvotes: 2

Related Questions