0

not sure if there’s a simple answer for this one. Well, I’m building a system / data base that I want to handle any kind of number in one field. Well, not sure if I need to give the specifics on the database structure, since the problem that I’m having, I’m able to replicate with a string.

I’m making a test with this number:

12312312312312312312312311.000000000000000000000000000000

But keep in mind that I’m looking for a solution that could handle also this number:

12312312312312312312312311.987987987987987987987987987987

My idea is to print out this exact value for both cases. But on the first case, print out:

12312312312312312312312311

So far, I’ve researched Stack Overflow and found this post:

How to avoid scientific notation for large numbers in JavaScript?

I’ve tried out some of the solutions, but none of them worked the way I expected.

I’ve also tried the following solution:

BigInt(12312312312312312312312311.000000000000000000000000000000)

But it prints out: 12312312312312311989665792 (very strange, by the way)

Anyone has any idea I could try out?

Thanks,

4
  • 3
    Does this answer your question? How to handle very big numbers in node js? Commented Feb 25, 2020 at 12:56
  • 1
    very strange => BigInt, firstly, there are no decimals in integers, that's why there called integers. Next when you define a bigInt, don't forget then suffix. eg. BigInt(12312312312312312312312311n) otherwise JS will cast from a double. Commented Feb 25, 2020 at 13:00
  • you can always use c/c++ lbraries in nodejs via napi Commented Feb 25, 2020 at 13:03
  • Hi Diego, I had taken a look at this post before and tried it out. It printed out: Invalid Number. Anyway, I was looking for a solution without any extra packages. Commented Feb 25, 2020 at 13:14

2 Answers 2

0

You can use this library: https://github.com/MikeMcl/bignumber.js/

const BigNumber = require('bignumber.js');

let x = new BigNumber("12312312312312312312312311.000000000000000000000000000000");

console.log(x.minus("0.012012012012012012012012012013").toFixed())
Sign up to request clarification or add additional context in comments.

10 Comments

With the number I gave as an example, printed out: Invalid Number.
try with passing number as a string
Hi Mr. Sirja, I tried both ways. Same result. For smaller numbers, works.
Your answer is right. I´ve made a test on my envirement and worked. Many thanks. I was passing as string, but now, the main problem is that it may be returning a different number due to how I´m extracting the data. The data is coming from a MySQL database field, configured like so: decimal(64, 30). When running the exact same code, I get this result: 12312312312312312000000000. And when running without any data treatment, I get this result: 1.2312312312312312e+25. Any idea on how I could handle this? Didn´t want to open another question to solve this. Again - many thanks!!!
I think I may have found the solution, in this post: stackoverflow.com/questions/50327557/… - basically, I had to add some special parameters in my MySQL connection string options {supportBigNumbers: true, bigNumberStrings: true}. It´s working perfectly now! Thanks!!
|
0

There's a Stage 1 proposal for a Decimal type for JavaScript, but being Stage 1 it's very early days.

In the meantime, you have a couple of options:

  1. There are various "big decimal" libraries you can find if you search for "JavaScript big decimal".

  2. You could use a wrapper around the new BigInt type and multiply your values by whatever minimum unit you need. For instance, for the examples given, you'd multiply by 1000000000000000000000000000000. On output, you'd insert the decimal place:

Here's an example of #2:

const multiplierString = "1000000000000000000000000000000";
const multiplier = BigInt(multiplierString);
const dotindex = multiplierString.length - 1;
const ex1 = BigInt("12312312312312312312312311000000000000000000000000000000");
const ex2 = BigInt("12312312312312312312312311987987987987987987987987987987");

function format(num) {
    let str = num.toString();
    str = str.substring(0, str.length - dotindex) + "." + str.substring(dotindex);
    return str;
}

console.log(format(ex1));
console.log(format(ex2));

If you liked, you could wrap that up into a utility class.

This is the same pattern used when dealing with much smaller fractional number values with JavaScript's traditional number type when precision is important. Financial applications can't use the traditional number type (because 0.1 + 0.2 === 0.3 is false due to IEEE-754 floating point imprecision), so they typically work in a base unit (say, instead of U.S. dollars, they work in cents or even hundreths of cents). The above is the same idea.

2 Comments

Hi T.J., I tried the js-big-decimal aproach, but it printed out: 12312312312312312000000000, when using the number I sent as an example.
@JorgeMauricio - I'm not familar with that library I'm afraid. You didn't create the "decimal" using a number as an argument did you? That's a mistake people often make, doing new BigDecimal(12312312312312312312312311987987987987987987987987987987) or similar. The problem with that is that the argument is a standard JavaScript number, which loses precision at that magnitude. So by the time the value gets to BigDecimal (or whatever), it's already too late, the data's been lost. Notice I'm using the BigInt(string) constructor above, for that reason.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.