How to output the number 2.00 as a complete string? - javascript

Before this, i want to say sorry. But this is not duplicate. Any answer on other posting has same problem. No float or int in JS (only number). When you make isInt() function, 2.00 always detected true as integer. I want 2.00 detected as float. So, i have to stringify it first.
function isInt(i) {
if ( i.toFixed ) {
if ( i % 1 === 0 ) {
return true; // the problem is 2.00 always detected true as integer.
// i want 2.00 detected as float
} else {
return false;
}
} else {
return false;
}
}
then i think i will stringify the 2.00 and then split it with split('.') . But toString doesn't do it
var i = 2.00;
alert(i.toString());
// Why this always result 2 . i want the character behind point
So, how to do that? i want 2.00 result "2.00" , not only "2"
Thank you for answering

You can use Number.toFixed(n);
var i = 2;
alert( i.toFixed(2) ); // "2.00"
var i = 1.2345;
alert( i.toFixed(2) ); // "1.23"
Also note that 2 === 2.00 but 2 !== "2.00".

Answer to revision:
Within javascript there is absolutely no way to distinguish between 2 2.0 and 2.000. Therefore, you will never without some additional decimal place supplied, be able to detect from var a = 2.00 that 2 was ever anything other than an integer (per your method) after it's been assigned.
Case in point, despite the [misleading] built-in methods:
typeof parseInt('2.00', 10) == typeof parseFloat('2.00')
'number' == 'number'
/* true */
Original Answer:
JavaScript doesn't have hard-based scalar types, just simply a Number. For that reason, and because you really only have 1 significant figure, JavaScript is taking your 2.00 and making it an "integer" [used loosly] (therefore no decimal places are present). To JavaScript: 2 = 2.0 = 2.00 = 2.00000).
Case in point, if I gave you the number 12.000000000000 and asked you to remember it and give it to someone a week from now, would you spend the time remember how many zeros there were, or focus on the fact that I handed you the number 12? (twelve takes a lot less effort to remember than twelve with as many decimal places)
As far as int vs float/double/real, you're really only describing the type of number from your perspective and not JavaScript's. Think of calling a number in JavaScript an int as giving it a label and not a definition. to outline:
Value: To JavaScript: To Us:
------ -------------- ------
1 Number integer
1.00 Number decimal
1.23 Number decimal
No matter what we may classify it as, JavaScript still only sees it as a Number.
If you need to keep decimal places, Number.toFixed(n) is going to be your best bet.
For example:
// only 1 sig-fig
var a = 2.00;
console.log(''+a); // 2
console.log(a.toFixed(2)); // 2.00
// 3 sig-figs
var b = 2.01
console.log(''+b); // 2.01
console.log(b.toFixed(2)); // 2.01
BTW, prefixing the var with ''+ is the same as calling a .toString(), it's just cast just shorthand. The same outcome would result if I had used a.toString() or b.toString()

To stringify (Chrome at least does so) use this:
i.toPrecision(3)
This will show 2 decimal digits.
Also NULL's solution does it very well without having to calculate the exact precision. i.e. .toFixed(decimals) is your best friend

You can't do exactly what you want to do.
2.00 gets converted to the number 2 in JavaScript, without decimal points. You can add it back in if you want using .toFixed(2), shown above.

I suggest keeping "2.00" as a string, as well as parsing it as a number, if necessary, for arithmetic. That way you can distinguish whether the number 2 was entered as "2", or "2.00", or "2.000000". Output the string, not the number, if you want to preserve the original number of decimal places.

Related

How to get digits from a BigInt in javascript?

I am working on problem n°104 of project Euler Problem 104 and would like to do it in javascript.
In order to solve this problem I need to compute large values of the Fibonacci sequence, but the numbers produced by this sequence are too large to be handle by classic Number, so I'm using BigInt supported in the latest versions of javascript.
Once I've got a particular result stored in a BigInt, I need to check it's 10 first, and last digits.
To get the digits from a Number we usually do something like in the code below, but when the number becomes very large, things go wrong:
let number = BigInt(123456789)
console.log(number.toString())
console.log(number.toString()[3]) // Result is fine
let bigNumber = BigInt(1234567891111111111111111111111111111)
console.log(bigNumber.toString())
console.log(bigNumber.toString()[30]) // unpredictable result
It seems like the "toString()" methods is only using the precision of the Number type (2^53 I believe), thus we are quickly losing precision on the last digits of the BigInt number. The problem is I can't find other methods to extract those digits.
Edit :
I need the precision to be perfect because basicaly what i'm doing for example is :
Compute Fibonacci(500) = 280571172992510140037611932413038677189525
Get the 10 last digits of this number : 8677189525 (this is where is lose the precision)
And then to solve my problem I need to check that those 10 last digits contains all the digits from 1 to 9
For big numbers, I think you should add the n suffix:
let number = BigInt(123456789)
console.log(number.toString())
console.log(number.toString()[3]) // Result is fine
let bigNumber = 1234567891111111111111111111111111111n // <-- n suffix, literal syntax
console.log(bigNumber.toString())
console.log(bigNumber.toString()[30]) // result
let bigNumber2 = BigInt('1234567891111111111111111111111111111') // <-- also works as a string, in case you can't use the literal for some reason
console.log(bigNumber2.toString())
console.log(bigNumber2.toString()[30]) // result

parsing string to decimal doesn't return decimals JavaScript

I'm new to writing JavaScript, I'm trying to convert two values from a string to a number, however, I have tried to doing the following approaches but none seem to work.
Example:
const num = parseInt('100.00') // returns 100
const num = Number('100.00') // returns 100
const num = +'100.00'; // returns 100
I need to return 100.00 as a number I have gone to other similar post they didn't seem to help, all knowledge is appreciated thanks!
In Javascript everything is Number, which is double-precision floating point 64 bit number (=decimal).
100.00 is equal to 100, therefore it shows you 100.
What you are asking is not possible, the decimal 100 is not representable as 100.00 as number, you can only represent it as a String with help of toFixed;
var num = 100;
var strNum = num.toFixed(2); // in this case you have a string instead of a number
console.log(typeof num, num);
console.log(typeof strNum, strNum);
It seems to me that all the approaches you have tried work.
Internally, JavaScript stores all numbers using the floating point format. It uses the minimum number of decimals needed when it displays the value.
This is 0 for integer numbers as 100. 100.00 is still 100, adding any number of 0 after the decimal point doesn't change its value.
The recommended method to parse a string that looks like a number is to use Number.parseInt() or Number.parseFloat().
parseFloat() recognizes only numbers written in base 10 but parseInt() attempts to detect the base by analyzing the first characters of the input string. It automatically recognizes numbers written in bases 2, 8, 10 and 16 using the rules described in the documentation page about numbers. This is why it's recommended to always pass the second argument to parseInt() to avoid any ambiguity.
Regarding your concern, use Number.toFixed() to force its representation using a certain number of decimal digits, even when the trailing digits are 0:
const num = parseInt('100.00');
console.log(num); // prints '100'
console.log(num.toFixed(2)); // prints '100.00'

numbers and toFixed , toPrecision in Javascript?

Regarding the famous issue of 1.01+1.02 which is 2.0300000000000002
one of the workarounds is to use toFixed : e.g.
(1.01+1.02).toFixed(2) --->"2.03"
But I saw a solution with toPrecision
parseFloat((1.01+1.02).toPrecision(10))-->"2.03"
But lets have a look at n in
toFixed(n)
toPrecision(n)
How would I know what is n ?
0.xxxxxxxxxxx
+
0.yyyyyyyyyyyyy
---------------------
0.zzzzzzzzzzzzzzzzzzzzzzzzz
^
|
-----??????------
each number being added can have a different decimal digits...
for example :
1.0002+1.01+1.03333--> 3.0435300000000005
how would I calculate the n here ? what is the best practice for this (specific) issue ?
For addition as in this situation I would check the number of decimal places in each operand.
In the simplest of situations the number of decimal places in the operand with the greatest number of decimal places is the value of n.
Once you have this, use which ever method you like to truncate your value. Then get rid of trailing zeros.
You may encounter trailing zeros in situations such as 1.06 + 1.04, the first step would take you to 1.10 then truncating the zero would give 1.1
In your last example 1.0002+1.01+1.03333 greatest number of decimal places is 5 so you are left with 3.04353 and there are no trailing zeros to truncate.
This returns the expected output:
function add(){
// Initialize output and "length" properties
var length = 0;
var output = 0;
// Loop through all arguments supplied to this function (So: 1,4,6 in case of add(1,4,6);)
for(var i = 0; i < arguments.length; i++){
// If the current argument's length as string is longer than the previous one (or greater than 0 in case of the first argument))
if(arguments[0].toString().length > length){
// Set the current length to the argument's length (+1 is to account for the decimal point taking 1 character.)
length = arguments[0].toString().length +1;
}
// Add the current character to the output with a precision specified by the longest argument.
output = parseFloat((output+arguments[i]).toPrecision(length));
}
// Do whatever you with with the result, here. Usually, you'd 'return output;'
console.log(output);
}
add(); // Returns 0
add(1,2,3); // Returns 6
add(1.01,2.01,3.03); // Returns 6.05
add(1.01,2.0213,3.3333); // Returns 6.3646
add(11.01,2.0213,31.3333); // Returns 44.3646
parseFloat even gets rid of trailing zero's for you.
This function accepts as many numbers as parameters as you wish, then adds these together taking the numbers' string length into account, when adding them. The precision used in the addition is dynamically modified to fit the "currently added" argument's length.
Fiddle
If you're doing calculations, you have a couple of choices:
multiply the numbers by eg 100, to convert to integers, then do the calculations, then convert back again
do the calculations, dont worry about the rounding errors, then round the result at display time
If you're dealing with money/currencies, the first option is probably not a bad option. If you're just doing scientific maths, I would personally not worry about it, and just round the results at display time, eg to 6 significant figures which is the default for my c++ compiler (gcc; not sure if it is in the c++ standards or not, but if you print 1.234567890 in gcc c++, the output is 1.23457, and the problem is avoided)
var a = 216.57421;
a.toPrecision(1); // => '200' because 216 with 1 < 5;
a.toPrecision(2); // => '220' because 216 with 6 >= 5;
a.toFixed(1); // => 216.6 because 7 >= 5;
a.toFixed(2); // => 216.57 because 4 < 5;

Validating a text field containing a float is a valid percentage value?

I have a form text field that has a KeyUp event. On KeyUp I'm ignoring anthing but numbers, the period, backspace, delete and cursor keys. So, the only thing in the field can be a number or period.
I need to verify these things (number will become a % not over 100.00%):
-The text field string is a valid number (which should always be true unless someone puts two '.'s in).
-The text field string has a max of 2 decimal places
-If the text field string has a decimal point, it has something after (1 or 2 decimal places, not just a period at the end)
-The number is not larger than 100 (<= 100)
examples (what I need to verify):
95 is true (valid, decimal places not required)
95. is false (don't need a '.' with no decimal place after)
95.0 is true
95.00 is true
95.000 is false (3 decimal places not valid) 100 is true
101.01 is false (over 100)
101 is false (over 100)
I've seen some things that do several pieces of that list, but I'm not smart enough to modify the regex to get exactly what I need. Thanks for any help!
Some people will suggest regexes, but I think a small function is better suited for such a validation:
function validate(x) {
var parts = x.split(".");
if (typeof parts[1] == "string" && (parts[1].length == 0 || parts[1].length > 2))
return false;
var n = parseFloat(x);
if (isNaN(n))
return false;
if (n < 0 || n > 100)
return false;
return true;
}
console.log(validate("95"));
console.log(validate("95."));
console.log(validate("95.0"));
console.log(validate("95.00"));
console.log(validate("95.000"));
console.log(validate("101.01"));
console.log(validate("101"));
Live example
try this expression: the 100% is a special case of a more generic pattern
var re = /^((0|[1-9]\d?)(\.\d{1,2})?|100(\.00?)?)$/;
explanation
(0|[1-9]\d?) allows numbers from 0 to 99
(\.\d{1,2})? allows a dot with 1 or 2 digits after
| otherwise
100 accept 100
(\.00?)? with optional 0 or 00
Edit:
I tried this jsfiddle demo http://jsfiddle.net/pCDVn/1/ and it's working... look at the console
You could limit the length of your field to 5, check that the value can be cast to a number, and then verify that the number is between 0 and 100. You won't be able to enter 100.00, but why would you need to?
Also, here's a fiddle for testing. One note, if you really care about validating "95." as false, you'll have to add extra validation for that. However, I'd advise against this requirement, because it is still represents a valid percentage and won't affect the outcome of calculations.

JavaScript - How To Detect Number As A Decimal (Including 1.0)

It feels like I am missing something obvious here. This has been asked a number of times - and the answer usually boils down to:
var num = 4.5;
num % 1 === 0; // false - 4.5 is a decimal
But, this fails for
var num = 1.0; // or 2.0, 3.0, ...
num % 1 // 0
Unfortunately, these doesn't work either
num.toString() // 1
typeof num // "number"
I am writing a JavaScript color parsing library, and I want to process input differently if it is given as 1.0 or 1. In my case, 1.0 really means 100% and 1 means 1.
Otherwise, both rgb 1 1 1 and rgb 1 255 255 will be parsed as rgb 255 255 255 (since I am right now taking anything <= 1 to mean a ratio).
Those numbers aren't actually decimals or integers. They're all floats. The only real difference between 1 and 1.0 is the notation that was used to create floats of equal values.
Edit: to help illustrate, consider:
1 === 1.0; // true
parseInt('1') == parseInt('1.0'); // true
parseFloat('1') === parseFloat('1.0'); // true
parseInt('1') === parseFloat('1'); // true
// etc...
Also, to demonstrate that they are really the same underlying data type:
typeof(1); // 'number'
typeof(1.0); // 'number'
Also, note that 'number' isn't unambiguous in JavaScript like it would be in other languages, because numbers are always floats.
Edit 2: One more addition, since it's relevant. To the best of my knowledge, the only context in JavaScript in which you actually have "real and true" integers that aren't really represented as floats, is when you're doing bitwise operations. However, in this case, the interpreter converts all the floats to integers, performs the operation, and then converts the result back to a float before control is returned. Not totally pertinent to this question, but it helps to have a good understanding of Number handling in JS in general.
Let your script parse the input as string, then it will be a matter of checking if there is the point like this.
mystring.indexOf('.');
Check this example and this example.
Number.isInteger(4.5)
Number.isInteger() is part of the ES6 standard and not supported in IE11.
You'll have to do it when parsing the string. If there's a decimal point in the string, treat it as percentage, otherwise it's just the integer value.
So, e.g.:
rgb 1 1 1 // same as #010101
rgb 1.0 1 1 // same as #ff0101
Since the rgb is there, you're parsing the string anyway. Just look for . in there as you're doing it.
Well, as far as the compiler is concerned, there is no difference between 1.0 and 1, and because there is no difference, it is impossible to tell the difference between them. You should change it from 1.0 to 100 for the the percentage thing. That might fix it.
var num = 1;
and
var num = 1.0;
are the same. You mention that you want to treat them differently when given from a user. You will want to parse the difference when it is still a string and convert it to the appropriate number.

Categories