Add trailing zeros to match precision dynamically - javascript

I am creating a react crypto project and just trying to figure out how to add trailing zeros dynamically without using the toFixed method. The reason why I am avoiding that toFixed method is because though it gets the precision right and tacks on desired trailing zeros, it rounds the number. Which can be misleading. So I am on the last part of getting this thing to operate correctly.
const getInternalAssetBalance = (selectedAsset, pairType, useFreeTotal = false) => {
const exchangeInternalAccount = holdingsByAccount.find(account => account.exchange === 'REGULAR');
const assetObj = exchangeInternalAccount && exchangeInternalAccount.assets.find(item => item.name === selectedAsset);
};
I have it where it limits the digits after the decimal based on precision(meaning it won't go over the precision specified), however, if a number happens to have less decimal places than the desired precision, it won't tack on the extra trailing zeros. For example lets say we have a number 12.353. If the precision was 5, I would want the result to be 12.35300. So that it tacks on the extra two zeros.
Anyone happen to know how I can dynamically tack on zeros if the balance amount happens to have fewer decimal places than the desired precision so that it matches?

A few remarks:
Since your function returns a number data type, you lose any format that wants to have trailing zeroes in the decimal part. A number value does not have any formatting that goes with it. Just like the native .toFixed method, you need to return a string.
You can still make use of the .toFixed method if you first make the truncation that is needed. This you can do by multiplying the number with a power of 10, truncate it to integer, and then divide it again.
function toFixed(n, precision) {
const coeff = 10**precision;
return (Math.floor(n * coeff) / coeff).toFixed(precision);
}
console.log(toFixed(1.234567, 4)); // 1.2345
console.log(toFixed(1.23, 4)); // 1.2300

Related

toFixed function on large numbers

I have following number with e+ on it
9.074701047887939e+304
I want to take only 9.07
So I tried below , but its not working , its returning full output
console.log(parseFloat(9.074701047887939e+304).toFixed(2));
Ps : I also need the code to work for normal numbers aswell for example 892.0747010 , should output 892.07
toFixed trims digits after the decimal point, but your actual number is very large - it doesn't have a decimal point.
If you don't know in advance whether the number is large or not, one option is to call toFixed(2) on the number first (trimming off and properly rounding digits past the decimal point for small numbers), then using a regular expression to take the numeric part only (removing the e if it exists), then call toFixed(2) again (trimming off and properly rounding digits past the decimal point for large numbers):
const fix = num => Number(
num.toFixed(2).match(/\d+(?:\.\d+)?/)[0]
).toFixed(2);
console.log(fix(9.074701047887939e+304));
console.log(fix(123.4567));
console.log(fix(12345));
Since you mentioned for both 9.074701047887939e+304 and 9.074701047887939, you want the answer to be 9.07.
For 9.074701047887939e-304 I assume you want 9.07 too, although you might actually want 0.00.
const twoDecimal = (a =>
(a.toString().match(/e/) ? Number(a.toString().match(/[^e]*/)[0]) : a).toFixed(2)
);
console.log(twoDecimal(9.074701047887939e+304));
console.log(twoDecimal(9.074701047887939e-304));
console.log(twoDecimal(9.074701047887939));
console.log(twoDecimal(789.074701047887939));
console.log(twoDecimal(0.00001));
console.log(twoDecimal(0.20001));
console.log(twoDecimal(-9.074701047887939e+304));
console.log(twoDecimal(-9.074701047887939e-304));
console.log(twoDecimal(-9.074701047887939));
console.log(twoDecimal(-789.074701047887939));
console.log(twoDecimal(-0.00001));
console.log(twoDecimal(-0.20001));
console.log(twoDecimal(0));

Intl formatting of huge floating point numbers

I'm trying to better understand why large numbers, with potentially large precisions are inconsistently handled, specifically in JavaScript and it's localization facilities (e.g. ECMA-402/Intl). I'm assuming this has to do with the use of floating point numbers, but I'd like to understand where the limits are and/or how to avoid these pitfalls.
For example, using Intl.NumberFormat:
console.log(new Intl.NumberFormat('en-US', { minimumFractionDigits: 3, maximumFractionDigits: 3 }).format(9999999999990.001)); // logs 9,999,999,999,990.000
let test1 = 9999999999990.001
console.log(test1); // logs 9999999999990.002
How would I be able to figure out where these numbers start to get inconsistent? Is there some kind of limit? Does that limit change as I increase decimal precision, e.g. :
let test2 = 9999999999990.0004;
console.log(test2) // logs 9999999999990
Is there some kind of limit? Does that limit change as I increase decimal precision?
Yes, and yes. Floating-point numbers in JavaScript are themselves stored in 64 bits of space, which means they are limited in the precision they can represent. See this answer for more information.
How would I be able to figure out where these numbers start to get inconsistent?
Pass your "numeric literals" to a function in the form of strings, and check to see if that string, when coerced to a number and back, returns the correct literal:
function safeNumber (s) {
if (String(+s) !== s)
throw new Error('Unsafe number!')
return +s
}
let safe = safeNumber('999999999999999')
console.log(safe)
let unsafe = safeNumber('9999999999990.001')
console.log(unsafe)

How can I parse a string as an integer and keep decimal places if they are zeros?

I have these strings: "59.50" & "30.00"
What I need to do is convert them to integers but keep the trailing zeros at the end to effectively return:
59.50
30.00
I've tried:
Math.round(59.50 * 1000) / 1000
Math.round(30.00 * 1000) / 1000
but ended up with
59.5
30
I'm assuming I need to use a different method than Math.round as this automatically chops off trailing zeros.
I need to keep these as integers as they need to be multiplied with other integers and keep two decimals points. T thought this would be fairly straight forward but after a lot of searching I can't seem to find a solution to exactly what I need.
Thanks!
Your premise is flawed. If you parse a number, you are converting it to its numerical representation, which by definition doesn't have trailing zeros.
A further flaw is that you seem to think you can multiply two numbers together and keep the same number of decimal places as the original numbers. That barely makes sense.
It sounds like this might be an XY Problem, and what you really want to do is just have two decimal places in your result.
If so, you can use .toFixed() for this:
var num = parseFloat("59.50");
var num2 = parseFloat("12.33");
var num3 = num * num2
console.log(num3.toFixed(2)); // 733.64
Whenever you want to display the value of the variable, use Number.prototype.toFixed(). This function takes one argument: the number of decimal places to keep. It returns a string, so do it right before viewing the value to the user.
console.log((123.4567).toFixed(2)); // logs "123.46" (rounded)
To keep the decimals - multiply the string by 1
example : "33.01" * 1 // equals to 33.01
Seems you are trying to retain the same floating point, so better solution will be some thing like
parseFloat(string).toFixed(string.split('.')[1].length);
If you want numbers with decimal points, you are not talking about integers (which are whole numbers) but floating point numbers.
In Javascript all numbers are represented as floating point numbers.
You don't need the trailing zeros to do calculations. As long as you've got all the significant digits, you're fine.
If you want to output your result with a given number of decimal values, you can use the toFixed method to transform your number into a formatted string:
var num = 1.5
var output = num.toFixed(2) // '1.50'
// the number is rounded
num = 1.234
output = num.toFixed(2) // '1.23'
num = 1.567
output = num.toFixed(2) // '1.57'
Here's a more detailed description of toFixed: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

Round float to 2 decimals javascript

I have the problem that when i round a number to 2 decimals the parseFloat() function removes .00 from the number. I have tried
var num = parseFloat(Math.round(19 * 100) / 100).toFixed(2);
The return: num="19.00"
The return i need: num = 19.00
I know 19 = 19.00, but i am using a service that always require two decimals .00
The function returns a string with the right value. When i parse it to float the .00 is removed.
You cannot get 19.00 as float, only as string, because numbers always remove trailing zeros.
Maybe you can show us a bit more code to get an idea, there you need these trailing zeros?
Numbers do and can not hold information about their representation. They are only a numerical value.
When you display a number using window.alert, console.log or similar, you are not looking at a number, but at a string. Those display functions convert numbers to strings before displaying them. Number.toFixed also converts numbers into strings, with the difference being that it rounds them to two decimal places, so you end up with another representation of the same number.
What I am trying to say is that to display a number, you cannot get around converting it to a string. Whether you do it explicitly or the display function does it for you. When you send the number to the service that you are using, you are probably also sending a string (JSON, XML, etc. are always strings once you send them). If you need the value of the number for calculations, use it, then convert it in the end. No matter how, you have to do it in the end if you want those 0's at the end.

Convert a Decimal number to float and truncate it

I have a number
For example:
8183
What I need is to convert it to a float number-
For example 8183
(8183).toFixed(2);
will return me
8183.00
But I need to truncate it further, so the final number will be
8.18
So basically I need to make it float number with just 2 decimal places.
I tried using the Math.floor and ceil but couldnt figure it out!
Well what you're trying to accomplish is not completely clear, but I think that if you start by dividing by 1000, then call toFixed on it, it will give you the desired result.
var before = 8183;
var after = (before / 1000).toFixed(2); //8.18
You could divide by 10 until you are less than 10:
var digits = 8183;
while((digits = digits/10) > 10) {}
digits = digits.toFixed(2); // 8.18
For negative numbers, you could want to store a boolean value and use Math.abs(digits).
For numbers less than 0, you would want to multiple instead of divide.
If all you really want is scientific notation use toExponential(2)

Categories

Resources