I have been trying to find a solution to the following problem. I have a string that is a floating-point number like,
var value = '12.30';
When I try to cast it to be a floating number
parseFloat('12.30'); // output is 12.3
I need a way for my logic to return 12.30, the actual value, and that too a number.
Solutions I checked used,
parseFloat('12.30').toFixed(2);
but this converts it to string type and that's not acceptable in my scenario.
Any help would be appreciated. Thanks!
It's not parseFloat()'s fault. Numerically speaking, 12.30 equals 12.3, even if you don't use parseFloat():
const x = 12.30;
console.log(x); // Prints "12.3"
You can just use unary plus from Type Conversions in JavaScript for get number value
var value = '12.30';
alert(parseFloat(value).toFixed(2)); // 12.30
alert(typeof +parseFloat(value).toFixed(2)); // number
Get new successess in development!
Problem
I need to return a number in the format of .66 (from an entered value which includes the leading zero, e.g. 0.66)
It must be returned as an integer with the decimal point as the first character.
what method in JavaScript can help me do this?
What have I tried?
I've tried converting it toString() and back to parseInt() but including the decimal point makes it return NaN.
I've tried adding various radix (10, 16) to my parseInt() - also unsuccessful
Sample Code
const value = 0.66;
if(value < 1) {
let str = value.toString().replace(/^0+/, '');
// correctly gets '.66'
return parseInt(str)
}
//result NaN
Expectations
I expect an output of the value with the leading 0 removed
e.g. 0.45 --> .45 or 0.879 --> .879
Current Observations
Output is NaN
I tried a quick solution, you may try to do this:
let a = 0.45;
// split on decimal, at index 1 you will find the number after decimal
let b = a.toString().split('.')[1];
Issue #1:
0.66 is not an Integer. An Integer is a whole number, this is a floating-point number.
Issue #2:
You cannot have a number in JavaScript that starts with a decimal point.
Even if you change your parseInt to be parseFloat, it will still return 0.66 as a result.
What you're asking just isn't possible, if you want a number to start with a decimal point then it has to be a string.
How do parseInt() and Number() behave differently when converting strings to numbers?
Well, they are semantically different, the Number constructor called as a function performs type conversion and parseInt performs parsing, e.g.:
// parsing:
parseInt("20px"); // 20
parseInt("10100", 2); // 20
parseInt("2e1"); // 2
// type conversion
Number("20px"); // NaN
Number("2e1"); // 20, exponential notation
Also parseInt will ignore trailing characters that don't correspond with any digit of the currently used base.
The Number constructor doesn't detect implicit octals, but can detect the explicit octal notation:
Number("010"); // 10
Number("0o10") // 8, explicit octal
parseInt("010"); // 8, implicit octal
parseInt("010", 10); // 10, decimal radix used
And it can handle numbers in hexadecimal notation, just like parseInt:
Number("0xF"); // 15
parseInt("0xF"); //15
In addition, a widely used construct to perform Numeric type conversion, is the Unary + Operator (p. 72), it is equivalent to using the Number constructor as a function:
+"2e1"; // 20
+"0xF"; // 15
+"010"; // 10
typeof parseInt("123") => number
typeof Number("123") => number
typeof new Number("123") => object (Number primitive wrapper object)
first two will give you better performance as it returns a primitive instead of an object.
One minor difference is what they convert of undefined or null,
Number() Or Number(null) Or Number('') // returns 0
while
parseInt() Or parseInt(null) // returns NaN
Summary:
parseInt():
Takes a string as a first argument, the radix (An integer which is the base of a numeral system e.g. decimal 10 or binary 2) as a second argument
The function returns a integer number, if the first character cannot be converted to a number NaN will be returned.
If the parseInt() function encounters a non numerical value, it will cut off the rest of input string and only parse the part until the non numerical value.
If the radix is undefined or 0, JS will assume the following:
If the input string begins with "0x" or "0X", the radix is 16 (hexadecimal), the remainder of the string is parsed into a number.
If the input value begins with a 0 the radix can be either 8 (octal) or 10 (decimal). Which radix is chosen is depending on JS engine implementation. ES5 specifies that 10 should be used then. However, this is not supported by all browsers, therefore always specify radix if your numbers can begin with a 0.
If the input value begins with any number, the radix will be 10
Number():
The Number() constructor can convert any argument input into a number. If the Number() constructor cannot convert the input into a number, NaN will be returned.
The Number() constructor can also handle hexadecimal number, they have to start with 0x.
Example:
console.log(parseInt('0xF', 16)); // 15
// z is no number, it will only evaluate 0xF, therefore 15 is logged
console.log(parseInt('0xFz123', 16));
// because the radix is 10, A is considered a letter not a number (like in Hexadecimal)
// Therefore, A will be cut off the string and 10 is logged
console.log(parseInt('10A', 10)); // 10
// first character isnot a number, therefore parseInt will return NaN
console.log(parseInt('a1213', 10));
console.log('\n');
// start with 0X, therefore Number will interpret it as a hexadecimal value
console.log(Number('0x11'));
// Cannot be converted to a number, NaN will be returned, notice that
// the number constructor will not cut off a non number part like parseInt does
console.log(Number('123A'));
// scientific notation is allowed
console.log(Number('152e-1')); // 15.21
If you are looking for performance then probably best results you'll get with bitwise right shift "10">>0. Also multiply ("10" * 1) or not not (~~"10"). All of them are much faster of Number and parseInt.
They even have "feature" returning 0 for not number argument.
Here are Performance tests.
I found two links of performance compare among several ways of converting string to int.
parseInt(str,10)
parseFloat(str)
str << 0
+str
str*1
str-0
Number(str)
http://jsben.ch/#/zGJHM
http://phrogz.net/js/string_to_number.html
parseInt() -> Parses a number to specified redix.
Number()-> Converts the specified value to its numeric equivalent or NaN if it fails to do so.
Hence for converting some non-numeric value to number we should always use Number() function.
eg.
Number("")//0
parseInt("")//NaN
Number("123")//123
parseInt("123")//123
Number("123ac") //NaN,as it is a non numeric string
parsInt("123ac") //123,it parse decimal number outof string
Number(true)//1
parseInt(true) //NaN
There are various corner case to parseInt() functions as it does redix conversion, hence we should avoid using parseInt() function for coersion purposes.
Now, to check weather the provided value is Numeric or not,we should use nativeisNaN() function
I always use parseInt, but beware of leading zeroes that will force it into octal mode.
It's a good idea to stay away from parseInt and use Number and Math.round unless you need hex or octal. Both can use strings. Why stay away from it?
parseInt(0.001, 10)
0
parseInt(-0.0000000001, 10)
-1
parseInt(0.0000000001, 10)
1
parseInt(4000000000000000000000, 10)
4
It completely butchers really large or really small numbers. Oddly enough it works normally if these inputs are a string.
parseInt("-0.0000000001", 10)
0
parseInt("0.0000000001", 10)
0
parseInt("4000000000000000000000", 10)
4e+21
Instead of risking hard to find bugs with this and the other gotchas people mentioned, I would just avoid parseInt unless you need to parse something other than base 10. Number, Math.round, Math.floor, and .toFixed(0) can all do the same things parseInt can be used for without having these types of bugs.
If you really want or need to use parseInt for some of it's other qualities, never use it to convert floats to ints.
parseInt converts to a integer number, that is, it strips decimals. Number does not convert to integer.
Another way to get the result is to use the ~ operator
For most circumstances
~~someThing === parseInt(something)
but ~~ will return zero for strings that parseInt will accept with trailing other characters or with the number base spec (eg hex) and will also return zero when parseInt returns NaN. Another difference is that ~~ if given a bigint returns a bigint to which you can add another bigint whereas parseInt returns an ordinary floating point number (yes really - it gives exactly the same value as parseFloat) if the bigint is large
However for most circumstances ~~ is 30% faster than parseInt. It is only slower by 10% when something is a floating point represented as a string.
So if the more restricted scope of ~~ fits your need then save the computer time and give yourself less to type
When I use p=10000 ,r=15 and n=60 in the below ...
var x = parseFloat((Math.round(r/12/100*p/(1-Math.pow(1+ +(r/12/100),-n))*100)/100).toFixed(2));
x = 237.9 instead of 237.90.
If the combo of p, r and n result in a number that is not $xx.x", then the code snippet works fine ...ie. formats to 2 decimal places.
But why is it displaying 237.9 instead of 237.90?
When you call number.toFixed(2), you do indeed get a string representation of the number with two decimal digits:
var number = 237.9;
number.toFixed(2); // '237.90'
However, when you then use parseFloat on this, you convert it back to a number again; since a number does not contain information about the number of zeros to display, the last zero is dropped as it is printed:
parseFloat(number.toFixed(2)); // 237.9
To avoid this, simply don't convert your string back into a float, but use it as a string.
var x = parseFloat((Math.round(r/12/100*p/(1-Math.pow(1+ +(r/12/100),-n))*100)/100)).toFixed(2);
p=10000,r=15, n=60;
var x = parseFloat((Math.round(r/12/100*p/(1-Math.pow(1+ +(r/12/100),-n))*100)/100)).toFixed(2);
console.log(x)
Add toFixed after all operations. You need string, basically...
I'm doing this:
var refundAmount = parseFloat($('#refundAmount2').val().replace('$',''));
var refundReceived = $('#refundReceived');
var remainderAmount = refundAmount-parseFloat(refundReceived.val().replace('$',''));
alert(parseInt(remainderAmount).toFixed(2));
No matter what I do, the result always ends with 2 decimal places being '.00'. So if the first number is 200.12 and the second is 100.08, it should be alerting me with 100.04 but instead I get 100.00.
Why might this be happening?
You used parseInt to convert that number to an integer and then used toFixed(2) to convert it to a number with 2 decimal places. Adding 2 decimal places to an integer will always result in .00.
Try
alert(remainderAmount.toFixed(2));
See DEMO.
You're getting it as an int with parseInt(), then doing the toFixed(). So you're putting decimal places on an int.