Convert whole number to one decimal in JavaScript - javascript

I got this issue.
I want to convert integer 71 (type number) to one decimal, meaning 71.0
but I need it to stay of type number.
Searched and the only solution I found was to use toFixed(1) and then parseFloat on
the result, and that does returns a number but 71, without the decimal.
const float = (num) => {
let fixed = (num).toFixed(1)
let float = parseFloat(fixed)
return float
}
float(71)
How should I do it?

This makes no sense, because an integer (whole number) will almost always equal its floating-point equivalent, unless there is a some odd precision behavior.
71 === 71.0
71 === 71.00
...
71 !== 71.000000001
Did you want to truncate a floating number using precision?
const truncateFloat = (n, p = 0) => parseFloat(n.toFixed(p));
// Truncate an irrational number (PI)
console.log(truncateFloat(Math.PI, 2) === 3.14) // true

Remove the parseFloat(fixed) and keep it as below
const float = (num) => {
let fixed = (num).toFixed(2)
//let float = parseFloat(fixed)
return float
}
float(71)
use toFixed(n) where n is the number of 10th places after the decimal.
You have stated that you need to keep it as number at the end but the thing is, if the decimals are 0, it will always round up to a whole number. So you may want to rather consider adding the toFixed(n) at the point of printing to the screen so they always print with that extra.
========= UPDATE
I just found a cleaner solution. consider the below with a link to the solution
const float = (num) => {
tmp = '0.00';
tmp = (+tmp + num).toFixed(2);
return tmp
}
float(71)
reference: how to get a float using parseFloat(0.00)

Related

How to round down integer to all zeros behind first number

For example, I need to round number 6588 => 6000 , 1285000 => 1000000
I can't find any Math.ceil , Math.floor methods that can achieve this.
You can divide by the highest power of ten, floor it, then multiply back by the highest power of ten. Some other answers are manipulating string, but IMO this is the simplest and easiest to read code. Like this:
function roundDown(num) {
let powerOfTen = num.toString().length - 1;
num /= (10**powerOfTen);
return Math.floor(num) * (10**powerOfTen);
}
console.log(roundDown(6588)) // => 6000
console.log(roundDown(1285000)) // => 1000000
This is roughly the same procedure that Math.floor() uses, as described in this MDN article;
another variant is just work on string level, instead of numbers to avoid any floating point problems
function roundToFirst(n) {
return (''+n).split('').map((c, i) => i > 0 ? '0' : c).join('');
}
console.log(roundToFirst(6588)); // 6000
console.log(roundToFirst(1285000)); // 1000000
You can convert your number to a string and simply append zeros to match the number's length.
const roundDown = (num) => {
num = num.toString();
return (num[0] + new Array(num.length).join('0'));
}
console.log(roundDown(6588))
console.log(roundDown(0))
A short and easy way is to take the first digit and padEnd the rest
const roundDown = num => {
num = String(num)
return +num[0].padEnd(num.length, "0")
}
console.log(roundDown(6588))
console.log(roundDown(1285000))
References
padEnd

Javascript: converting very large and very small numbers to a fixed human readbale string

I have the following function which I thought would convert very large e.g., 1e+24 and very small, e.g., 1e-18 numbers to a fixed string, e.g., 1000000000000000000000000:
convertExponentialToDecimal (exponentialNumber) {
// Sanity Check - i.e., is it exponential number?
const str = exponentialNumber.toString()
if (str.indexOf('e-') !== -1) {
const exponent = parseInt(str.split('-')[1], 10)
return exponentialNumber.toFixed(exponent)
}
if (str.indexOf('e+') !== -1) {
const exponent = parseInt(str.split('+')[1], 10)
return exponentialNumber.toFixed(exponent)
}
return exponentialNumber
}
However, for very large numbers - the process seems not to be working ...
i.e., a conversion of 1e+24 yields 1e+24, but 1e-18 yields 0.000000000000000001 as expected.
Can anyone spot the obvious issues, or have any pointers or even their own working solution for such a scenario...
If this is any insight - it works for anything less than 1e+21 ...
For your 'very large' part:
if (str.indexOf('e+') !== -1) {
let [a,b] = str.split('+')
a = a.slice(0,-1)
if (a.indexOf('.') !== -1) {
b = parseInt(b) - (a.length - a.indexOf('.') -1)
}
return a.replace('.','')+"".padEnd(b,0)
}
For your 'very small' part (though this would need to be tested, it works on my example but i didn't go through corner cases) :
if (str.indexOf('e-') !== -1) {
const [a,b] = str.split('-')
return '0.'+a.slice(0,-1).padStart(b,0).replace('.','')
}
Number type is IEEE754 float with double precision behind the curtain and it doesn't have enough precision to represent 1e24 digits. If you want to avoid treating numbers as strings, consider BigInt data type.
There are BigInt literals with n suffix and they don't support exponential notation, but luckily they do support **. For big numbers, you can use
10n**24n; // 1000000000000000000000000n
BigInts, are Int, without decimal point. But they are also Big, so you can afford fixed point notation, like first thousand digits are integer part, second thousand digits decimal part (the maximum size depends on available memory).

Sum Strings as Numbers

I am trying to solve a kata that seems to be simple on codewars but i seem to not be getting it right.
The instruction for this is as simple as below
Given the string representations of two integers, return the string representation of the sum of those integers.
For example:
sumStrings('1','2') // => '3'
A string representation of an integer will contain no characters besides the ten numerals "0" to "9".
And this is what i have tried
function sumStrings(a,b) {
return ((+a) + (+b)).toString();
}
But the results solves all except two and these are the errors i get
sumStrings('712569312664357328695151392', '8100824045303269669937') - Expected: '712577413488402631964821329', instead got: '7.125774134884027e+26'
sumStrings('50095301248058391139327916261', '81055900096023504197206408605') - Expected: '131151201344081895336534324866', instead got: '1.3115120134408189e+29'
I don't seem to understand where the issues is from. Any help would help thanks.
The value you entered is bigger than the int type max value. You can try changing your code to:
function sumStrings(a,b) {
return ((BigInt(a)) + BigInt(b)).toString();
}
This way it should return the right value
You could pop the digits and collect with a carry over for the next digit.
function add(a, b) {
var aa = Array.from(a, Number),
bb = Array.from(b, Number),
result = [],
carry = 0,
i = Math.max(a.length, b.length);
while (i--) {
carry += (aa.pop() || 0) + (bb.pop() || 0);
result.unshift(carry % 10);
carry = Math.floor(carry / 10);
}
while (carry) {
result.unshift(carry % 10);
carry = Math.floor(carry / 10);
}
return result.join('');
}
console.log(add('712569312664357328695151392', '8100824045303269669937'));
console.log(add('50095301248058391139327916261', '81055900096023504197206408605'));
The problem is that regular javascript integers are not having enough space to store that much big number, So it uses the exponential notation to not lose its precision
what you can do is split each number into parts and add them separately,
one such example is here SO answer
My solution is:
function sumStrings(a,b) {
return BigInt(a) + BigInt(b) + ''
}
Converting from a string to a number or vice versa is not perfect in any language, they will be off by some digits. This doesn't seem to affect small numbers, but it affects big numbers a lot.
The function could go like this.
function sumStrings(a, b) {
return (BigInt(a) + BigInt(b)).toString() // or parseInt for both
}
However, it's still not perfect since if we try to do:
console.log((4213213124214211215421314213.0 + 124214321214213434213124211.0) === sumStrings('4213213124214211215421314213', '124214321214213434213124211'))
The output would be false.

Adding Two Decimal Places using JavaScript

Good day Everyone!
I want to know how to return the output with two decimal places. Instead of 10,000 I want it to return 10,000.00. Also I already put .toFixed(2) but it's not working.
When the amount has decimal number other than zero, the values appear on the printout, but when the decimal number has a zero value, the Zeros won't appear on the printout.
Also, I have added a value of Wtax that was pulled-out on a "Bill Credit" Transaction.
Output:
Numeral.js - is a library that you can use for number formatting.
With that you can format your number as follows:
numeral(10000).format('$0,0.00');
Hope this will help you.
You can try this
var x = 1000; // Raw input
x.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,') //returns you 1,000.00
Alternately you can use Netsuite's currency function too
nlapiFormatCurrency('1000'); // returns you 1,000.00
nlapiFormatCurrency('1000.98'); // returns you 1,000.98
You might consider below code. It can round off decimal values based on the decimal places.
This also addresses the issue when rounding off negative values by getting first the absolute value before rounding it off. Without doing that, you will have the following results which the 2nd sample is incorrect.
function roundDecimal(decimalNumber, decimalPlace)
{
//this is to make sure the rounding off is correct even if the decimal is equal to -0.995
var bIsNegative = false;
if (decimalNumber < 0)
{
decimalNumber = Math.abs(decimalNumber);
bIsNegative = true;
}
var fReturn = 0.00;
(decimalPlace == null || decimalPlace == '') ? 0 : decimalPlace;
var multiplierDivisor = Math.pow(10, decimalPlace);
fReturn = Math.round((parseFloat(decimalNumber) * multiplierDivisor).toFixed(decimalPlace)) / multiplierDivisor;
fReturn = (bIsNegative) ? (fReturn * -1) : fReturn;
fReturn = fReturn.toFixed(decimalPlace)
return fReturn;
}
Below are the test sample
And this test sample after addressing the issue for negative values.

Javascript: Comparing two float values [duplicate]

This question already has answers here:
Javascript float comparison
(2 answers)
Closed 6 months ago.
I have this JavaScript function:
Contrl.prototype.EvaluateStatement = function(acVal, cfVal) {
var cv = parseFloat(cfVal).toFixed(2);
var av = parseFloat(acVal).toFixed(2);
if( av < cv) // do some thing
}
When i compare float numbers av=7.00 and cv=12.00 the result of 7.00<12.00 is false!
Any ideas why?
toFixed returns a string, and you are comparing the two resulting strings. Lexically, the 1 in 12 comes before the 7 so 12 < 7.
I guess you want to compare something like:
(Math.round(parseFloat(acVal)*100)/100)
which rounds to two decimals
Compare float numbers with precision:
var precision = 0.001;
if (Math.abs(n1 - n2) <= precision) {
// equal
}
else {
// not equal
}
UPD:
Or, if one of the numbers is precise, compare precision with the relative error
var absoluteError = (Math.abs(nApprox - nExact)),
relativeError = absoluteError / nExact;
return (relativeError <= precision);
The Math.fround() function returns the nearest 32-bit single precision float representation of a Number.
And therefore is one of the best choices to compare 2 floats.
if (Math.fround(1.5) < Math.fround(1.6)) {
console.log('yes')
} else {
console.log('no')
}
>>> yes
// More examples:
console.log(Math.fround(0.9) < Math.fround(1)); >>> true
console.log(Math.fround(1.5) < Math.fround(1.6)); >>> true
console.log(Math.fround(0.005) < Math.fround(0.00006)); >>> false
console.log(Math.fround(0.00000000009) < Math.fround(0.0000000000000009)); >>> false
Comparing floats using short notation, also accepts floats as strings and integers:
var floatOne = 2, floatTwo = '1.456';
Math.floor(floatOne*100) > Math.floor(floatTwo*100)
(!) Note: Comparison happens using integers. What actually happens behind the scenes: 200 > 145
Extend 100 with zero's for more decimal precision. For example use 1000 for 3 decimals precision.
Test:
var floatOne = 2, floatTwo = '1.456';
console.log(Math.floor(floatOne*100), '>', Math.floor(floatTwo*100), '=', Math.floor(floatOne*100) > Math.floor(floatTwo*100));
Comparing of float values is tricky due to long "post dot" tail of the float value stored in the memory. The simplest (and in fact the best) way is: to multiply values, for reducing known amount of post dot digits to zero, and then round the value (to rid of the tail).
Obviously both compared values must be multiplied by the same rate.
F.i.: 1,234 * 1000 gives 1234 - which can be compared very easily. 5,67 can be multiplied by 100, as for reducing the float comparing problem in general, but then it couldn't be compared to the first value (1,234 vel 1234). So in this example it need to be multiplied by 1000.
Then the comparition code could look like (in meta code):
var v1 = 1.234;
var v2 = 5.67;
if (Math.round(v1*1000) < Math.round(v2*1000)) ....

Categories

Resources