1

I have a function that performs mathematical calculations on various numbers, including decimal numbers, and returns two string and numeric outputs. The problem I have with numeric output for decimal numbers is that it is a scientific notation. After several hours of searching the internet and seeing similar questions on stackoverflow and github, I finally came up with a combination of several functions to get to a point where the string output is smooth and accurate. But numerical output is still a problem and the result is a scientific notation.

so I decided to ask a question here, maybe I can find help for my problem

now consider sending the two numbers 2.5183213 and 2.518321 with the subtraction sign and the number of 8 decimal places to the main function of the following code snippet

the string output will be 0.0000003 and the numeric output will be 3e-7. While the numerical output should be equal to 0.0000003 and of numerical type

snippet sample

// main function
function decFix(num1, num2, operation, lentDec = 8, outType = "number") {
    num1 = Number(num1).toFixed(lentDec);
    num2 = Number(num2).toFixed(lentDec);
    let result = 0

    if (operation == "+") {
        if (outType === "string") {
            result = `${toFixed(Number((num1 + num2).toFixed(lentDec)))}`
        } else {
            result = Number((num1 + num2).toFixed(lentDec))
        }
    } else if (operation === "-") {
        if (outType === "string") {
            result = `${toFixed(Number((num1 - num2).toFixed(lentDec)))}`
        } else {
            result = Number((num1 - num2).toFixed(lentDec))
        }
    } else if (operation === "/") {
        if (outType === "string") {
            result = `${toFixed(Number((num1 / num2).toFixed(lentDec)))}`
        } else {
            result = Number((num1 / num2).toFixed(lentDec))
        }
    } else if (operation === "*") {
        if (outType === "string") {
            let multiplication = toFixed(Number((num1 * num2).toFixed(lentDec)))
            if (countDecimals(multiplication) > lentDec) {
                result = `${Number(multiplication).toFixed(lentDec)}`
            } else {
                result = `${multiplication}`
            }
        } else {
            result = Number((num1 * num2).toFixed(lentDec))
        }
    }
    return result
}

// count the number of available decimals
let countDecimals = function (value) {
    if (Math.floor(value) !== value)
        return value.toString().split(".")[1].length || 0;
    return 0;
}

// convert scientific notation numbers to normal numbers (output type will be string)
function toFixed(x) {
    if (Math.abs(x) < 1.0) {
        let e = parseInt(x.toString().split('e-')[1]);
        if (e) {
            x *= Math.pow(10, e - 1);
            x = '0.' + (new Array(e)).join('0') + x.toString().substring(2);
        }
    } else {
        let e = parseInt(x.toString().split('+')[1]);
        if (e > 20) {
            e -= 20;
            x /= Math.pow(10, e);
            x += (new Array(e + 1)).join('0');
        }
    }
    return x;
}



let a = 2.5183213
let b = 2.518321

let c = decFix(a, b, "-", 8, "string")
let d = decFix(a, b, "-", 8, "number")
let e = a - b

document.querySelector('#stringOutPut').innerHTML = `decFix string output: ${c} - type: ${typeof c}`
document.querySelector('#numericOutPut').innerHTML = `decFix numeric output: ${d} - type: ${typeof d}`
document.querySelector('#normalOutPut').innerHTML = `normal subtraction output: ${e}`
<div id="stringOutPut"></div>
----------------------------
<div id="numericOutPut"></div>
----------------------------
<div id="normalOutPut"></div>
  • You're looking for [`.toPrecision()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Number/toPrecision), which is a more capable variation of the `.toString()` method. – Pointy Jun 05 '21 at 18:57
  • @pointy The result of toPrecision() will be a string value while I need a numeric value, I also tried several ways including toPrecision() method but eventually after converting the result to numeric type the value becomes a scientific notation – Saeed Noroozi Jun 05 '21 at 19:11
  • 1
    When you set the `.innerHTML` it's going to be turned into a string anyway. Numbers are not in any particular notation while they're numbers, except for the internal binary floating point representation. – Pointy Jun 05 '21 at 19:12
  • @pointy I use this function in a node.js project, so it's important to me that the output type is numeric, and the only reason to use innerHTML here is the ease of displaying the output. – Saeed Noroozi Jun 05 '21 at 19:20
  • "output type is numeric" does not make any sense. If the number is rendered into a string of characters you can look at, it's a string. – Pointy Jun 05 '21 at 19:23
  • @pointy Maybe I did not explain correctly, I have a process in the backend that is supposed to perform a series of consecutive calculations so that the result of the previous calculation is used as input to the new calculation. And since in JavaScript it is not possible to perform mathematical calculations on a numerical and string value together, it is therefore necessary that the results of previous calculations be numerical. Unless there is a better way to do mathematical calculations on all numbers, whether decimal or non-decimal, in which case I will be happy to choose that way. – Saeed Noroozi Jun 05 '21 at 19:42
  • 1
    @pointy But consider how difficult it is to do calculations on decimal numbers in JavaScript. For example, a result of 0.3 - 0.1 would normally be something like 0.2, while in javascript the result would be about 0.199999999999999999998. and that's the root of the problem that made me write such a function – Saeed Noroozi Jun 05 '21 at 19:46
  • But numbers in JavaScript are all numbers; they're all the same. They're IEEE 754 floating point values, which is the way almost all modern computer hardware represents numbers. It's a *binary* floating point system, which means that the mantissa is a *binary* fraction, not a decimal fraction. That's just the way it is. If you need real decimal-based math, you *might* be able to work with "bigint" values, but those are always integer values. – Pointy Jun 05 '21 at 22:37

0 Answers0