'Javascript: How can I add two strings without converting into numbers?
Given two numbers in string format (eg. '10.23' and '25.69') how can I get their sum without converting the string into numbers? (eg '35.92') I do not want to convert the strings into numbers using things like parseInt, Number, parseFloat etc....
Solution 1:[1]
An old trick is to multiply by 1, as that forces numeric conversion. The * operator doesn't work on strings, so it forces a switch to numbers. It's an old trick though, as I said.
The unary plus operator is a more modern.
var num1 = '20',
num2 = '30.5';
console.log(num1 * 1 + num2 * 1); // = '50.5'
If you want the output to definitely be a string, you can also:
console.log((num1 * 1 + num2 * 1)+"");
Solution 2:[2]
Disclaimer: I am not recommending you actually do this. However, you could implement your own add method using a pre calculated lookup table and a rough implementation of a "binary" adder (converted into decimal). The code below work for your example, but i leave no guarantee that it will work for any general cases.
const lookupTable = Array(10).fill(0)
.map((_, i) => Array(10).fill(0)
.map((_, j) => [`${i},${j}`, i+j+'']))
.reduce((flatArr, innerArr) => [...flatArr, ...innerArr], [])
.reduce((lookupTable, [k, v]) => ({...lookupTable, [k]: v}), {})
const addDigits = (a, b) => {
const sum = lookupTable[`${a},${b}`];
if (sum.length === 2) return [sum[1], '1'];
else return [sum, '0'];
}
const strAdd = (a, b) => {
const add = ([aH, ...aT], [bH, ...bT], carryBit='0') => {
if (aH === undefined && aH === undefined) return '';
if (aH === undefined) return add([], bT, carryBit) + bH;
if (bH === undefined) return add(aT, [], carryBit) + aH;
if (aH === '.' || bH === '.') return add(aT, bT, carryBit) + '.';
const [partial_sum, partial_carryBit1] = addDigits(aH, bH);
const [sum, partial_carryBit2] = addDigits(partial_sum, carryBit);
const [newCarryBit] = addDigits(partial_carryBit1, partial_carryBit2);
return add(aT, bT, newCarryBit) + sum;
}
const [whole_a, decimal_a] = a.split('.');
const [whole_b, decimal_b] = b.split('.');
const wholeMaxLength = Math.max(whole_a.length, whole_b.length)+1;
const decimalMaxLength = Math.max((decimal_a || '0').length, (decimal_b || '0').length);
a = whole_a.padStart(wholeMaxLength, '0') + '.' + (decimal_a || '').padEnd(decimalMaxLength, '0');
b = whole_b.padStart(wholeMaxLength, '0') + '.' + (decimal_b || '').padEnd(decimalMaxLength, '0');
return add([...a].reverse(), [...b].reverse(), '0')
.replace(/^0+/, '') // remove leading 0
.replace(/0+$/, '') // remove trailing 0
.replace(/\.$/, '') // remove trailing .
}
const calc = (a, b, expected) => {
const result = strAdd(a, b);
console.log(result, result === expected);
}
calc('10.23', '25.69', '35.92');
calc('1', '2', '3');
calc('10.3', '2', '12.3');
calc('99999', '1.01', '100000.01');
Solution 3:[3]
Here's the solution for your problem:
const format_numStr = (num, no_of_digits, digits_Arr) => {
outNum = 0
no_of_digits-=1
for (digit of num) {
if (digits_Arr.includes(digit)) {
// power of 10 decreases as digits progress from left to right i.e from 10^(len(num)-1) to 10^0
// index() Method returns the exact number or digit we pass in type integer
outNum+=(digits_Arr.indexOf(digit)*10**(no_of_digits))
no_of_digits-=1
}
};
return outNum
}
const numStr_Sum = (numStr_Arr) => {
digits_Arr = Array.from(new Array(10), (_, i) => String(i)) //array contains digits from [0-9]
num_Arr=[] // Initialise an array to store the given str number as type integer
numStr_Arr.forEach(num => {
no_of_digits = num.length
if (num.includes('.')) {
decimal_val = num.split('.')[1].length // Gives the Decimal point (.) position value
//Since period(.) exists in the num, no_of_digits should be decreased by 1
float_num = format_numStr(num, no_of_digits-1,digits_Arr)/10**decimal_val
num_Arr.push(float_num)
}
else {
num_Arr.push(format_numStr(num, no_of_digits, digits_Arr))
}
});
total_sum = num_Arr.reduce((a,b)=>a+b,0)
if (Number.isInteger(total_sum)) {
return total_sum
}
else {
return total_sum.toFixed(decimal_val)
}
}
console.log(numStr_Sum(['22.22','22.22']))
Solution 4:[4]
You can use the unary plus operator (+), but in the background it is converting the string into numbers anyway.
Example:
+string1 + +string2
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | |
Solution 4 | Gabriel Tetzlaf |