How to convert from Base36 to Base10 in JS - javascript

I have a base36 number 00001CGUMZYCB99J
But if I try convert it in JavaScript to base 10 with
parseInt("00001CGUMZYCB99J", 36);
I get wrong results like 177207000002463650 or 177207000002463648. The expected result is 177207000002463655. I found two websites that get the result right anyway: translatorscafe and dcode.
But how can I do this in JS?

The outcome of that conversion exceeds Number.MAX_SAFE_INTEGER (i.e. the base-10 value is too large to fit in a JavaScript integer), which means you need some sort of arbitrary precision library to do the conversion, for instance biginteger:
const BigInteger = require('biginteger').BigInteger;
let value = BigInteger.parse('00001CGUMZYCB99J', 36);
console.log( value.toString() ) // 177207000002463655

JavaScript stores all values in a double. Therefore, large numbers will have some of the less significant digits changed. If you want to deal with large numbers, you have to use a special library like this BigInteger one.
If you use this library, you can convert between bases like this:
BigInteger.parse("00001CGUMZYCB99J", 36);
Keep in mind that you need to keep using the library, you can't convert it back into a normal number, or you will face the same problem.

Related

Javascript: prevent parseFloat from converting large number to scientific notation

I have some data in a node app which are numbers in string format. I'm trying to parse them and round off to 3 decimals by parseFloat(num).toFixed(3). Since the numbers are very large, it is automatically converting them to scientific notation (eg 2.0210702881736412e+37). I switched to using parseInt(), Number() but nothing works. How do I get around this?
The data object is very huge so I'm skeptical to use a custom converter function which converts the exponential form to decimal, since it might impact performance.
Use BigInt
const num = BigInt(2.0210702881736412e+37);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
BigInt values are similar to Number values in some ways, but also differ in a few key matters: A BigInt value cannot be used with methods in the built-in Math object and cannot be mixed with a Number value in operations; they must be coerced to the same type. Be careful coercing values back and forth, however, as the precision of a BigInt value may be lost when it is coerced to a Number value.
How you use BigInt for it: BigInt(n).toString();
const num = BigInt(2.0210702881736412e+37);
// 20210702881736411847466551731631947776n
const strNum = num.toString();
// 20210702881736411847466551731631947776
Edit, additional info
Bigint library (or also the builtin data type) can only handle integers. I think try the JavaScript numeric operation library seems to be the fastest way to calculate the decimal point. A bignumber library typically works with arbitrary-precision floating-point numbers. There are several recommended libraries.
bignumber.js Or BigNumber

Add trailing zeros to an integer without converting to string in JS?

I'm looking to add decimals to the end of my integer. As an example:
15 => 15.00
The problem with methods like toFixed is that it will convert it into a string. I've tried to use parseFloat() and Number() on the string, but it'll convert it back to an integer with no decimals.
Is this possible? If not, can someone explain to me the logic behind why this isn't possible?
EDIT: Welp the intent was to display the number as a number, but from the going consensus, it looks like the way the only way to go about it is to use a string. Found an answer on the why: https://stackoverflow.com/a/17811916/8869701
The problem you are finding is that all numbers in javascript are floats.
a = 0.1
typeof a # "number"
b = 1
typeof b # number
They are the same.
So there is no real way to convert to from an integer to a float.
This is the reason that all of the parseFloat etc are string methods for reading and writing numbers from strings. Even if you did have floats and integers, specifying the precision of a number only really makes sense when you are displaying it to a user, and for this purpose it will be converted to a string anyway.
Depending on your exact use case you will need to use strings if you want to display with a defined precision.
When working with numbers 15 and 15.00 are equal. It wouldn't make any sense to use memory to store those trailing or leading zeros.
If that information is needed it is usually for displaying purposes. In that case a string is the right choice.
In case you need that value again you can parse the string as a number.

Parse big binary strings to base 10

I'm having some trouble converting big binary strings to base 10. parseInt(string, 2) should return the int, but when using big strings (1800 characters) it maxes out the variable and just returns Infinity. How can get around that?
A 1800 bit binary number would be well over the maximum possible number value in JavaScript. A regular number datatype will not be able to hold that value, and so JavaScript just calls it Infinity. If you need arbitrarily large numbers, you will have to use some bignum library and probably write a custom string to number function.

Why isn't value obtained after Masking accurate in JavaScript?

I was trying to extract last 32 bits from a Hex number in Javascript.
var hex = 0x6C469F301DBBC30;
var last32bit = (hex & 0xFFFFFFFF).toString(16);
log(last32bit); //gives 1dbbc40
The result is 1DBBC40. Shouldn't this supposed to be 1DBBC30 ?
Also how do I preserve the 0 before 1DBBC40?
The ECMA standard says:
The Number type has exactly 18437736874454810627 (that is, 264−253+3)
values
Your number is too large to be represented exactly by a Number. You should look for a big number library if you wish to accurately represent large numbers. Perhaps one of these libraries would meet your needs.

Javascript can't render this number correctly: 3494793310847464221

I have an interesting question, I have been doing some work with javascript and a database ID came out as "3494793310847464221", now this is being entered into javascript as a number yet it is using the number as a different value, both when output to an alert and when being passed to another javascript function.
Here is some example code to show the error to its fullest.
<html><head><script language="javascript">alert( 3494793310847464221);
var rar = 3494793310847464221;
alert(rar);
</script></head></html>
This has completly baffeled me and for once google is not my friend...
btw the number is 179 more then the number there...
Your number is larger than the maximum allowed integer value in javascript (2^53). This has previously been covered by What is JavaScript's highest integer value that a Number can go to without losing precision?
In JavaScript, all numbers (even integral ones) are stored as IEEE-754 floating-point numbers. However, FPs have limited "precision" (see the Wikipedia article for more info), so your number isn't able to be represented exactly.
You will need to either store your number as a string or use some other "bignum" approach (unfortunately, I don't know of any JS bignum libraries off the top of my head).
Edit: After doing a little digging, it doesn't seem as if there's been a lot of work done in the way of JavaScript bignum libraries. In fact, the only bignum implementation of any kind that I was able to find is Edward Martin's JavaScript High Precision Calculator.
Use a string instead.
179 more is one way to look at it. Another way is, after the first 16 digits, any further digit is 0. I don't know the details, but it looks like your variable only stores up to 16 digits.
That number exceeds (2^31)-1, and that's the problem; javascript uses 32-bit signed integers (meaning, a range from –2,147,483,648 to 2,147,483,647). Your best choice is to use strings, and create functions to manipulate the strings as numbers.
I wouldn't be all too surprised, if there already was a library that does what you need.
One possible solution is to use a BigInt library such as: http://www.leemon.com/crypto/BigInt.html
This will allow you to store integers of arbitrary precision, but it will not be as fast as standard arithmetic.
Since it's to big to be stored as int, it's converted to float. In JavaScript ther is no explicit integer and float types, there's only universal Number type.
"Can't increment and decrement a string easily..."
Really?
function incr_num(x) {
var lastdigit=Number(x.charAt(x.length-1));
if (lastdigit!=9) return (x.substring(0,x.length-1))+""+(lastdigit+1);
if (x=="9") return "10";
return incr_num(x.substring(0,x.length-1))+"0";
}
function decr_num(x) {
if(x=="0") return "(error: cannot decrement zero)";
var lastdigit=Number(x.charAt(x.length-1));
if (lastdigit!=0) return (x.substring(0,x.length-1))+""+(lastdigit-1);
if (x=="10") return "9"; // delete this line if you like leading zero
return decr_num(x.substring(0,x.length-1))+"9";
}
Just guessing, but perhaps the number is stored as a floating type, and the difference might be because of some rounding error. If that is the case it might work correctly if you use another interpreter (browser, or whatever you are running it in)

Categories