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,

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Jorge Mauricio
  • 411
  • 6
  • 18
  • 3
    Does this answer your question? [How to handle very big numbers in node js?](https://stackoverflow.com/questions/46428372/how-to-handle-very-big-numbers-in-node-js) – Diego Desenvolvedor Feb 25 '20 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 the`n` suffix. eg. `BigInt(12312312312312312312312311n)` otherwise JS will cast from a double. – Keith Feb 25 '20 at 13:00
  • you can always use c/c++ lbraries in nodejs via napi – Estradiaz Feb 25 '20 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. – Jorge Mauricio Feb 25 '20 at 13:14

2 Answers2

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())
Meet Siraja
  • 173
  • 1
  • 10
  • With the number I gave as an example, printed out: Invalid Number. – Jorge Mauricio Feb 25 '20 at 13:16
  • try with passing number as a string – Meet Siraja Feb 25 '20 at 13:20
  • Hi Mr. Sirja, I tried both ways. Same result. For smaller numbers, works. – Jorge Mauricio Feb 25 '20 at 13:28
  • Edited answer!! added example. It is working. You can check npm runkit demo here: https://runkit.com/embed/5hgtx3kzldh1 – Meet Siraja Feb 25 '20 at 13:33
  • Hi Mr. Sirja, I tried with the first example number (12312312312312312312312311.000000000000000000000000000000) and it printed out: 12312312312312312000000000 Did you get this result also or am I doing something wrong? – Jorge Mauricio Feb 25 '20 at 13:50
  • Yes, Maybe you are not passing number ras a string. Just check out this example: https://runkit.com/embed/eyq8twj27ebx – Meet Siraja Feb 26 '20 at 04:28
  • In Number, it can handle up to 15 significant digits. For more, you need to pass a number as a string. – Meet Siraja Feb 26 '20 at 04:40
  • 1
    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!!! – Jorge Mauricio Feb 26 '20 at 11:52
  • I didn't get you exactly. Please consider opening another question & yeah I'm happy to help you. – Meet Siraja Feb 26 '20 at 11:58
  • 1
    I think I may have found the solution, in this post: https://stackoverflow.com/questions/50327557/what-is-the-best-way-to-handle-big-number-returning-from-database-in-nodejs - basically, I had to add some special parameters in my MySQL connection string options {supportBigNumbers: true, bigNumberStrings: true}. It´s working perfectly now! Thanks!! – Jorge Mauricio Feb 26 '20 at 12:03
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.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Hi T.J., I tried the js-big-decimal aproach, but it printed out: 12312312312312312000000000, when using the number I sent as an example. – Jorge Mauricio Feb 25 '20 at 13:27
  • @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. – T.J. Crowder Feb 25 '20 at 14:28