How to change the limit of toFixed() function in js? - javascript

I want to be able to use standard toFixed() function with an arbitrary number (official allows using values between 0 and 20)
I don't know how to change the limit, so I found this library allowing to specify an arbitrary number:
https://github.com/MikeMcl/big.js/blob/master/big.js
I don't want to use the whole library just to able to run this one function. Please help me to understand how does this library implementing this arbitrary length toFixed() function?
update:
For example in python, a module called Decimal can calculate as many floating digits as you want:
>>> num1 = 4857932878236943867839468934782
>>> num2 = 1328768938470-2699462978
>>> result = Decimal(num1) / Decimal(num2)
>>> result
3663407512215411920.125441595041830470639118971082230413476294397448265790489938870721

Or you can just use simple function
var numberStr = '20.83953272434765327423485345342342345';
function toFixed(nbr, precision) {
let nSplit = nbr.split('.');
return nSplit[0] + '.' + nSplit[1].substring(0, precision);
}
console.log( toFixed(numberStr, 22) );
//or you could extend String.prototype as
String.prototype.toLongFixed = function(precission) {
let split = this.split('.');
return split[0] + '.' + split[1].substring(0, precission);
}
console.log( numberStr.toLongFixed(33) );

Related

represent decimal numbers in javascript as "%g" formatting in C

I have a number generated as a finite decimal:
var x = k * Math.pow(10,p)
with k and p integers. Is there a simple way to convert it to an exact string representation?
If I use implict string conversion I get ugly results:
""+ 7*Math.pow(10,-1)
gives
"0.7000000000000001"
I tried using .toFixed and .toPrecision but it is very difficult to find the correct precision to use depending on k and p. Is there a way to get the good old "%g" formatting of C language? Maybe I should resort to an external library?
One can use math.format from math.js library:
math.format(7 * Math.pow(10, -1), {precision: 14});
gives
"0.7"
You can create your own floor function like this, with option accuracy
function fixRound(number, accuracy) {
return ""+Math.floor(number * (accuracy || 1)) / accuracy || 1;
}
let num = 7 * Math.pow(10, -1);
console.log(fixRound(num, 1000))

How to keep the zero's when parsing two strings to a float value

I'm trying to create a function that converts two strings to a float value.
Some external party created a theme with a backend where you should provide to values for a price:
priceBeforeComma
priceAfterComma
In the html this converts to:
<span>55,<sup>07</sup></span>
I need to do some calculations with the price as a float before splitting it up again for the html like you can see above.
I have a function that works pretty fine:
function parsePrice(price, priceDecimal) {
return parseFloat(price + "." + priceDecimal);
}
However, the problem I'm facing is that let's say I provide 07 as the decimal like above, the leading zero is removed, returning 55,7.
There is quite a big difference between 55,07 and 55,7. I expect to get back the zero as well like 55,07.
Any help will be much appreciated.
Your Code is right
function parsePrice(price, priceDecimal) {
return parseFloat(price + "." + priceDecimal);
}
parsePrice("55", "07");
if you send parsePrice("55","07") so you do not need to divide it by 100 because maybe you send it 007 then you should divide it by 1000. But your code will work properly if send string
Floats represent 07 as 07.0, so to get this to work correctly you'll need to write it as 0.07.
Here's what worked for me:
function parsePrice(price, priceDecimal) {
return parseFloat(price + priceDecimal);
}
var output = parsePrice(57, 0.07);
document.getElementById("test").innerHTML = output.toString().replace(".", ",");
<p id="test"></p>
This might be overkill, but you could use something that provides complete control over how numbers are converted to strings, and vice versa, for example: https://github.com/alexei/sprintf.js I have not used that library, but it promises to provide the same functionality as C printf, which would allow you to keep leading zeros. See the answer to the "C" language question here: Printing leading 0's in C?
(But, as an aside, also see my comment above - generally it's better to do financial calculations in integer arithmetic rather than floating point.)
So my suggestion would be to do this instead:
function price(dollars, cents) { // adjust for your currency
return parseInt(dollars)*100 + parseInt(cents);
}
function dollarsAndCents(price) {
let sign = "+";
if (price<0) {
sign = "-";
price = -price;
}
let cents = price % 100;
let dollars = (price-cents)/100;
dollars = dollars.toString();
cents = cents.toString();
if (cents.length<2) cents = "0" + cents;
return {sign: sign, dollars: dollars, cents: cents}
}
let price1 = price ("55", "07");
let price2 = price ("99", "99");
let total = price1 + price2;
console.log(dollarsAndCents(total))
//{ sign: '+', dollars: '155', cents: '06' }
let refund = -12345
console.log(dollarsAndCents(refund))
//{ sign: '-', dollars: '123', cents: '45' }
There you go, that's a pretty complete solution! Even handles negative amounts.
You should pass in Strings to your function instead by putting quotes around your numbers. Using numbers will always have the caveat of removing any leading zeroes.
function parsePrice(price, priceDecimal) {
return parseFloat(price + "." + priceDecimal);
}
parsePrice("55", "07");
Why not parse them separately as integers and add them together in the right proportions?
function parsePrice(price, priceDecimal) {
return parseInt(price) + (parseInt(priceDecimal) / 100);
}
console.log(parsePrice("55", "07"));

How to display more than 20 decimal points in javascript?

I am making a webpage that displays the digits of pi. I was able to get my pi variable to display 20 digits of pi using the toFixed method but I am wondering if I can display more. Is the number of decimal places limited by the memory size of my variable? Is there a way to display more than 20 digits?
EDIT: I should have clarified that I was using the Chudnovsky Algorithmn to calculate the value of pi. I assuming that because of the memory limitations of the var variable that it can only display up to a certain amount of digits which is limited to 20? Source
You can't do this with native JavaScript for more info see this.
The following is cast to float:
var x = 3.14159265358979323846;
print(x.toFixed(20));
However, you can either print a string or to use mathjs:
var one = math.bignumber(1);
var pi = math.bignumber('3.14159265358979323846');
var ans = math.multiply(one, pi);
print(ans.toString());
Will give you "3.14159265358979323846"
You can't.
Try storing the bits in more than one variable, use a string, or get a bignum library, or if you only need to deal with integers, a biginteger library.
I'll cheat:
var pi = '3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019';
var piDecimal = function(numDigits) {
return pi.substr(0, numDigits + 2); // Add 2 to compensate for "3."
};
for (var i = 1; i < 100; i++) {
console.log(i + ' decimal place' + (i === 1 ? '' : 's') + ': ' + piDecimal(i));
}

parseInt not converting decimal to binary?

From my understanding the binary number system uses as set of two numbers, 0's and 1's to perform calculations.
Why does:
console.log(parseInt("11", 2)); return 3 and not 00001011?
http://www.binaryhexconverter.com/decimal-to-binary-converter
Use toString() instead of parseInt:
11..toString(2)
var str = "11";
var bin = (+str).toString(2);
console.log(bin)
According JavaScript's Documentation:
The following examples all return NaN:
parseInt("546", 2); // Digits are not valid for binary representations
parseInt(number, base) returns decimal value of a number presented by number parameter in base base.
And 11 is binary equivalent of 3 in decimal number system.
var a = {};
window.addEventListener('input', function(e){
a[e.target.name] = e.target.value;
console.clear();
console.log( parseInt(a.number, a.base) );
}, false);
<input name='number' placeholder='number' value='1010'>
<input name='base' placeholder='base' size=3 value='2'>
As stated in the documentation for parseInt: The parseInt() function parses a string argument and returns an integer of the specified radix (the base in mathematical numeral systems).
So, it is doing exactly what it should do: converting a binary value of 11 to an integer value of 3.
If you are trying to convert an integer value of 11 to a binary value than you need to use the Number.toString method:
console.log(11..toString(2)); // 1011
.toString(2) works when applied to a Number type.
255.toString(2) // syntax error
"255".toString(2); // 255
var n=255;
n.toString(2); // 11111111
// or in short
Number(255).toString(2) // 11111111
// or use two dots so that the compiler does
// mistake with the decimal place as in 250.x
255..toString(2) // 11111111
The parseInt() function parses a string argument and returns an integer of the specified radix (the base in mathematical numeral systems).
So you are telling the system you want to convert 11 as binary to an decimal.
Specifically to the website you are referring, if you look closer it is actually using JS to issue a HTTP GET to convert it on web server side. Something like following:
http://www.binaryhexconverter.com/hesapla.php?fonksiyon=dec2bin&deger=11&pad=false
The shortes method I've found for converting a decimal string into a binary is:
const input = "54654";
const output = (input*1).toString(2);
print(output);
I think you should understand the math behind decimal to binary conversion. Here is the simple implementation in javascript.
main();
function main() {
let input = 12;
let result = decimalToBinary(input);
console.log(result);
}
function decimalToBinary(input) {
let base = 2;
let inputNumber = input;
let quotient = 0;
let remainderArray = [];
let resultArray = [];
if (inputNumber) {
while (inputNumber) {
quotient = parseInt(inputNumber / base);
remainderArray.push(inputNumber % base);
inputNumber = quotient;
}
for (let i = remainderArray.length - 1; i >= 0; i--) {
resultArray.push(remainderArray[i]);
}
return parseInt(resultArray.join(''));
} else {
return `${input} is not a valid input`;
}
}
This is an old question, however I have another solution that might contribute a little bit. I usually use this function to convert a decimal number into a binary:
function dec2bin(dec) {
return (dec >>> 0).toString(2);
}
The dec >>> 0 converts the number into a byte and then toString(radix) function is called to return a binary string. It is simple and clean.
Note: a radix is used for representing a numeric value. Must be an integer between 2 and 36. For example:
2 - The number will show as a binary value
8 - The number will show as an octal value
16 - The number will show as an hexadecimal value
function num(n){
return Number(n.toString(2));
}
console.log(num(5));
This worked for me: parseInt(Number, original_base).toString(final_base)
Eg: parseInt(32, 10).toString(2) for decimal to binary conversion.
Source: https://www.w3resource.com/javascript-exercises/javascript-math-exercise-3.php
Here is a concise recursive version of a manual decimal to binary algorithm:
Divide decimal number in half and aggregate remainder per operation until value==0 and print concatenated binary string
Example using 25: 25/2 = 12(r1)/2 = 6(r0)/2 = 3(r0)/2 = 1(r1)/2 = 0(r1) => 10011 => reverse => 11001
function convertDecToBin(input){
return Array.from(recursiveImpl(input)).reverse().join(""); //convert string to array to use prototype reverse method as bits read right to left
function recursiveImpl(quotient){
const nextQuotient = Math.floor(quotient / 2); //divide subsequent quotient by 2 and take lower limit integer (if fractional)
const remainder = ""+quotient % 2; //use modulus for remainder and convert to string
return nextQuotient===0?remainder:remainder + recursiveImpl(nextQuotient); //if next quotient is evaluated to 0 then return the base case remainder else the remainder concatenated to value of next recursive call
}
}
To get better understanding, I think you should try to do the math of that conversion by yourself.
(1) 11 / 2 = 5
(1) 5 / 2 = 2
(0) 2 / 2 = 1
(1) 1 / 2 = 0
I made a function based on that logic
function decimalToBinary(inputNum) {
let binary = [];
while (inputNum > 0) {
if (inputNum % 2 === 1) {
binary.splice(0,0,1);
inputNum = (inputNum - 1) / 2;
} else {
binary.splice(0,0,0);
inputNum /= 2;
}
}
binary = binary.join('');
console.log(binary);
}
This is what I did to get the solution:
function addBinary(a,b) {
// function that converts decimal to binary
function dec2bin(dec) {
return (dec >>> 0).toString(2);
}
var sum = a+b; // add the two numbers together
return sum.toString(2); //converts sum to binary
}
addBinary(2, 3);
I first converted the decimal number to binary like it said, and I got the function from w3schools under the JavaScript Bitwise lesson. Then to make it easier on myself, I created the variable "sum" which does the addition and finally, I made the addBinary function return the sum as a binary code, then called it. It passed in CodeWars. I hope this makes sense and it helps you.
Just use Number(x).toString(base). Where base needs to be equals 2.
var num1=13;
Number(num1).toString(2)
result: "1101"
Number(11).toString(2)
result: "1011"
It seems like the conversion with the string radix (dec >>> 0).toString(2) is returning the binary number formatted in the wrong direction. I have validated this solution in Chrome. In case anyone wants to manually calculate binary for validation, from left to right you add the numbers together that correspond to a 1 position in your binary number mapping to [1][2][4][8][16][32][64][128] ....
For example:
10 in binary is 0101 OR 0 + 2 + 0 + 8.
13 in binary is 1011 OR 1 + 0 + 4 + 8.
255 in binary is 11111111 OR 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128
function dec2bin(dec){
return (dec >>> 0).toString(2).split('').reverse().join('');
}
This will give the decimal to binary:
let num = "1234"
console.log(num.toString(2));
This will give binary to decimal:
let num = "10011010010";
console.log(parseInt(num, 2));

Convert A Large Integer To a Hex String In Javascript

I need to find a way to convert a large number into a hex string in javascript. Straight off the bat, I tried myBigNumber.toString(16) but if myBigNumber has a very large value (eg 1298925419114529174706173) then myBigNumber.toString(16) will return an erroneous result, which is just brilliant. I tried writing by own function as follows:
function (integer) {
var result = '';
while (integer) {
result = (integer % 16).toString(16) + result;
integer = Math.floor(integer / 16);
}
}
However, large numbers modulo 16 all return 0 (I think this fundamental issue is what is causing the problem with toString. I also tried replacing (integer % 16) with (integer - 16 * Math.floor(integer/16)) but that had the same issue.
I have also looked at the Big Integer Javascript library but that is a huge plugin for one, hopefully relatively straightforward problem.
Any thoughts as to how I can get a valid result? Maybe some sort of divide and conquer approach? I am really rather stuck here.
Assuming you have your integer stored as a decimal string like '1298925419114529174706173':
function dec2hex(str){ // .toString(16) only works up to 2^53
var dec = str.toString().split(''), sum = [], hex = [], i, s
while(dec.length){
s = 1 * dec.shift()
for(i = 0; s || i < sum.length; i++){
s += (sum[i] || 0) * 10
sum[i] = s % 16
s = (s - sum[i]) / 16
}
}
while(sum.length){
hex.push(sum.pop().toString(16))
}
return hex.join('')
}
The numbers in question are above javascript's largest integer. However, you can work with such large numbers by strings and there are some plugins which can help you do this. An example which is particularly useful in this circumstance is hex2dec
The approach I took was to use the bignumber.js library and create a BigNumber passing in the value as a string then just use toString to convert to hex:
const BigNumber = require('bignumber.js');
const lrgIntStr = '1298925419114529174706173';
const bn = new BigNumber(lrgIntStr);
const hex = bn.toString(16);

Categories