Are there floating-point numbers in JavaScript? - javascript

I see many questions about methods to detect if a value is a floating-point number, but none of the examples work on numbers like as 1.0, 5.0, etc.
Is it possible to distinguish between numbers like 1 and 1.0 or 5 and 5.0? If yes, how can you detect a floating-point variable type?

In Ecmascript 6, you can use isInteger:
var value = . . .;
Number.isInteger(value);
However, this is not widely supported yet. For now, you can use this:
function isInteger(value) {
return typeof value === 'number' && (value | 0) === value;
}
This should work for all integer values that can be represented exactly in a 64-bit floating point representation.

I think the more concise answer is this one :
In javascript : 5 === 5.0.
So from this point on, no way can be found to distinguish them.
They are strictly the same thing.
Edit : reminder : the only x such as (x!==x) in javascript is NaN.

Zerstoren, the others are technically right: in javascript if you enter 2.0 or 2, there is no difference on how data is stored internally, so there is no way to find out if data was originally written as integer or float.
However, in case you want to validate some user form data, so that the user enters only integer numbers (e.g. order 2 pizzas, not 2.0) then the you do have a solution because that's actually a string (hence "2.0" is not same as "2"). You can use
typeof(n) =="string" && parseInt(n, 10) == n && n.indexOf('.')==-1
The first typeof condition is so that you fall under data is still in string format case I mentioned. See here: http://jsfiddle.net/X6U2d/
Andrei

There is no such thing as a float or int basic types in JavaScript, only a number. So, there is no difference between 5.0 and 5.
If it is important to you (for whatever reason), you will need to store the value as a string then use parseFloat to extract the value.
For example:
var int = "5";
var float = "5.0";
console.log(int == float); // false
console.log(parseFloat(int) == parseFloat(float)); // true
How to print numbers to fixed number of decimal places
I've just spotted Zerstoren comment: "i get data from mongodb and want to print this data with strong typing."
The method toFixed can be used to print a number to fixed number of decimal places:
var num = 5;
console.log( num.toFixed(1) ); // 5.0

Related

How can I store a very very large number in JavaScript?

What if I want to store a very very large number and then display it. For example factorial of 200.
How can I do this using JavaScript?
I tried the normal way and the result is null or infinity.
function fact(input) {
if(input == 0) {
return 1;
}
return input * fact(input-1);
}
var result = fact(171);
console.log(result);
I tried in normal way and the result is infinity or null.
It seems JavaScript can generate Factorial up to 170.
Look at this picture. This calculator seems able to do it.
The BigInt numeric type is going to be implemented in the future of JavaScript, the proposal is on Stage 3 on the ECMAScript standardization process and it's being supported by major browsers now.
You can use either the BigInt constructor or the numeric literal by appending an n at the end of the number.
In older environments you can use a polyfill.
function fact(input) {
if(input == 0n) {
return 1n;
}
return input * fact(input-1n);
}
const result = fact(171n);
console.log(String(result));
Try this javascript based BigInteger library. There are many to choose from. But i recommend this one https://github.com/peterolson/BigInteger.js
Example:
var num = bigInt("9187239176928376598273465972639458726934756929837450")
.plus("78634075162394756297465927364597263489756289346592");

Ext.util.Format.number add extra decimals

I'm using method "Ext.util.Format.number" to convert a value to string, according to a specific format.
But this method add extra (parasite) decimal.
With this code :
var strValue = Ext.util.Format.number(value, this.displayFormat);
For example if
displayFormat = "0,000.00############"
value = 102.15
After conversion, strValue is not equals to 102.15 but to 102.15000000000001
Is there any way to be sure that "Ext.util.Format.number" never add extra/parasite decimal ?
Thanks
Since 102.15 and 102.15000000000001 are not distinguishable(*) in JavaScript, it's up to you to choose a number format that does not include that many digits. Ext.util.Format.number has no way to determine the correct output.
(*) try 102.15 === 102.15000000000001 in your javascript console - it returns true
Do parseFloat(strValue) after that formatting. I think thats what you are looking for.

Dynamic number.toFixed() function

I am using javascript number.toFixed() function.
My problem is I have to explicitly mention number of fractional length like below:
if number is 1e11 then I have to specifiy it as
number.toFixed(2)
or if number is 1e1 then :
number.toFixed(1)
or if its 1e0 then
number.toFixed(0)
I want to do it dynamically based on whether fractions present or not. and irrespective of fractional length.
I dont want to pass parameter of fixed fractional length. js should dynamically understand fractional length of it. Is there similar provision in JS? or is there any similar function in java script where I need not to explicitly pass parameter of fixed length?
var temp = number.split('.');
if (typeof temp[1] !== 'undefined') {
console.log(temp[1].length); // here you got it
} else {
// 0
}

Javascript function to determine if a value is an integer

I came across a problem where I needed to determine if the field being entered by the user was an integer or float. The answer would then preselect a drop down further along a form. After much digging I found lots of framework code but none that actually did the job properly. The test data I used was;
Blank answer,
Non Numeric (Alpha),
1.0,
10,
1.10,
2.4,
3.0,
0.30,
0.00
A lot of other posts were also tested with the above data and I could not find one that passed ALL of the data correctly.
So I have written the following so that it may be reviewed by your good selves and hopefully it will help someone else out should they come across the same situation.
function isInteger(value)
{
//if(isNaN(value))return Nan;//optional check
//test for decimal point
if(!( /^-?\d+$/.test(String(value))))
{
//decimal point found
//if parseInt changes value it must be a float
if(parseInt(value) / 1 != value)return false;
}
//no decimal point so must be integer
return true;
}
Testing for integer values
ECMAScript 6 standard introduces a Number.isInteger().
This function is not yet supported by all major browsers, but a polyfill is listed on the site:
Number.isInteger = Number.isInteger || function isInteger (value) {
return typeof value === 'number' &&
isFinite(value) &&
Math.floor(value) === value
}
In case of user input (which is a string, not an integer), we can use the Number function to perform a type conversion into a number:
var input = '123' // Imagine this came from user
if (Number.isInteger(Number(input)) {
// User entered a valid integer value
}
Note, however, that the type conversion returns a valid integer-like value even for hexadecimal or octal strings. If this is not desired, you would need to further validate the original string. For detailed information about how the type conversion works, see MDN.
If such strict validation is desired, MDN also provides a good implementation using Regex (see the link for example output):
function filterInt (value) {
if(/^(\-|\+)?([0-9]+|Infinity)$/.test(value))
return Number(value)
return NaN
}
Testing for floating point numbers
isFinite() in combination with Number.isInteger() can help achieve our goal.
In case of user input (which is a string, not a float), we must use the Number function to perform a type conversion into a number:
var input = '123.5'
// Perform type conversion to a number
input = Number(input)
if (Number.isFinite(input) && ! Number.isInteger(input)) {
// A finite number that is not an integer can only be a float
}
Alternatively, a stricter variant of the parseFloat() implementation may be used instead, as listed on MDN (see the link for example output):
function filterFloat (value) {
if(/^(\-|\+)?([0-9]+(\.[0-9]+)?|Infinity)$/
.test(value))
return Number(value)
return NaN
}
Since you've mentioned user inputs, your question is about strings, so Number.isInteger is not an option.
To answer this question correctly we have to define more precisely what "integer" means when applied to strings. Is it
a sequence of digits? (example: ১২৪৫)
or a sequence of arabic digits? (example: 0000001)
or any mathematically valid integer representation? (example: 989238402389402394820394802)
or a mathematically valid integer that can be represented exactly in Javascript (i.e. it's less than MAX_SAFE_INTEGER)?
My guess is that you're looking for 4), here's the code for this case:
function isValidIntegerRepresentation(str) {
return /^-?\d+$/.test(str) && String(Number(str)) === str;
}
test = ['0', '00', '123', '-123', '239482039482309820394820394'];
test.forEach(function(n) {
document.write(n + "=" + isValidIntegerRepresentation(n) + "<br>");
});
This is very similar to what you already have.

Angular giving error "Model is not of type `number`" when typeof === number

As a work around to not being able to filter inputs without directives I've attempted the following:
On the input ngChange detects a change and runs a function. The input has type="number"
<input type="number"
ng-model="ctrl.met.mass"
ng-change="ctrl.met.update.mass()">
The function updates some other fields, then formats them. In this example I want it to display two decimal points with toFixed(2). This is done with variable = variable.toFixed(2)
ctrl.met.cost = ctrl.met.mass * ctrl.met.price;
ctrl.imp.mass = ctrl.met.mass * 0.0353;
ctrl.imp.cost = ctrl.imp.mass * ctrl.imp.price;
console.log(typeof ctrl.met.mass); // number
ctrl.met.mass = ctrl.met.mass.toFixed(2);
console.log(typeof ctrl.met.mass); //string
But the number isn't formatting as well as I'm receiving this error; note the number at the end of the URL is 29.00, being the desired result. If the number is 12.34 that would be in place of 29.00.
Error: ngModel:numfmt
Model is not of type `number`
But when I run typeof ctrl.met.mass at any point, or any other variable I'm working with, it's telling me it is in fact a number except after .toFixed() has interacted with it.
The same error has occurred with the Angular Number Filter (after injecting), parseInt(), parseFloat(), and toPrecision() (to a precision of 4, to ensure two decimal places for a two digit number).
ctrl.met.mass = $filter("number")(ctrl.met.mass, 2);
ctrl.met.mass = $filter("number")(parseInt/Float/Precision(ctrl.met.mass), 2);
ctrl.met.mass = ctrl.met.mass.toInt/Float
ctrl.met.mass = ctrl.met.mass.Precision(4);
I'm thinking I won't be able to do so this way, and will need to use a directive. Before I try that though, why is this happening and can it be worked around?
edit: It seems what I'm trying is impossible. Upon setting ctrl.met.mass to what was, without a doubt, a number with two decimal places it rejected it in preference for an integer. If anyone knows why this is the case, please share.
The returned value from the toFixed method is a string. So you need to convert it to float in your controller:
var fixed = ctrl.met.mass.toFixed(2);
ctrl.met.mass = parseFloat(fixed);
you can make a stringToNumber directive to parse string to number, the perfect example of this is shown at below link :
https://docs.angularjs.org/error/ngModel/numfmt

Categories