This question already has answers here:
issue with comparing two numbers in javascript
(5 answers)
Closed 4 months ago.
I have this javascript function to validate if a number is greater than another number
function validateForm() {
var x = document.forms["frmOrder"]["txtTotal"].value;
var y = document.forms["frmOrder"]["totalpoints"].value;
if (x > y) {
alert("Sorry, you don't have enough points");
return false;
}
}
It's not working for some reason.
If I do alert(x) I get 1300, and alert(y) gives 999
This works....
function validateForm() {
var x = 1300;
var y = 999;
if (x > y) {
alert("Sorry, you don't have enough points");
return false;
}
}
You should convert them to number before compare.
Try:
if (+x > +y) {
//...
}
or
if (Number(x) > Number(y)) {
// ...
}
Note: parseFloat and pareseInt(for compare integer, and you need to specify the radix) will give you NaN for an empty string, compare with NaN will always be false, If you don't want to treat empty string be 0, then you could use them.
You're comparing strings. JavaScript compares the ASCII code for each character of the string.
To see why you get false, look at the charCodes:
"1300".charCodeAt(0);
49
"999".charCodeAt(0);
57
The comparison is false because, when comparing the strings, the character codes for 1 is not greater than that of 9.
The fix is to treat the strings as numbers. You can use a number of methods:
parseInt(string, radix)
parseInt("1300", 10);
> 1300 - notice the lack of quotes
+"1300"
> 1300
Number("1300")
> 1300
You can "cast" to number using the Number constructor..
var number = new Number("8"); // 8 number
You can also call parseInt builtin function:
var number = parseInt("153"); // 153 number
Do this.
var x=parseInt(document.forms["frmOrder"]["txtTotal"].value);
var y=parseInt(document.forms["frmOrder"]["totalpoints"].value);
Related
This question already has answers here:
Math.pow with negative numbers and non-integer powers
(2 answers)
Closed 3 years ago.
I am trying to write a code about changing numbers to its cube root but whenever i enter a negative number, i receive NaN error.
Tried to use string to number function called Number
let number = prompt("Enter a number");
if (number > 0 || number < 0){
let x = number**(1/3);
alert(x);
}
else if (number == 0){
alert(number);
}
else{
alert("Error");
}
I enter -8 for example, i expect it will give me -2 as result but i receive NaN
This is because cube-root of a negative number has complex numbers as solutions along with a negative real number, to get the negative real number you have to write a simple logic:
function cubeRoot(number){
const isNegative = number < 0;
const cubeRoot = Math.pow(Math.abs(number), 1/3);
return isNegative ? -cubeRoot : cubeRoot;
}
console.log(cubeRoot(-8));
console.log(cubeRoot(0));
console.log(cubeRoot(8));
There is a library available to do this: math.js
console.log(math.cbrt(-8));
console.log(math.cbrt(0));
console.log(math.cbrt(8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/6.2.1/math.js"></script>
I am doing an online test and it asks me to write basic javascript code.
It asks me to parse a numberic string and convert it to a number of a different base. It needs me to return -1 if for whatever reason the conversion cannot be done.
I have written this:
function convert(strNumber, radix) {
var result = parseInt(strNumber, radix);
if(isNaN(result))
{return -1;}
return result;
}
Then it runs my code through various tests and all pass. Except one.
Apparently convert("ASD", 15) should be invalid according to the test and it expects it to be -1.
But Javascript happily converts it to number 10
I tried various things such as to add a try{}catch{} block and other things, but javascript never complains about converting "ASD" to base 15.
Is the test wrong, or is parseInt wrong?
By the way strNumber can be any base under 36.
So for instance:
convert("Z", 36) is 35
As I stated in the comment, parseInt will convert up to the point where it fails. So "A" is valid in that radix and "S" is not. So you would need to add a check.
var nums = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".substr(0, radix)
var re = new RegExp("^[" + nums + "]+$","i")
if (!re.test(strNumber)) {
return -1
}
parseInt is behaving normally and is converting the letter A into 10 in base 15 (similar to how hex uses A for the number 10). The S and D are discarded, as parseInt accepts this type of malformed input.
From the parseInt documentation:
If parseInt encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters and returns the integer value parsed up to that point.
As per official documentation the parseInt function behaves as following
For radices above 10, the letters of the alphabet indicate numerals
greater than 9. For example, for hexadecimal numbers (base 16), A
through F are used.
and
If parseInt encounters a character that is not a numeral in the
specified radix, it ignores it and all succeeding characters and
returns the integer value parsed up to that point.
Thus to prevent invalid arguments from being parsed they have to be validated first
function convert(strNumber, radix) {
if (isValidRadix(radix) && isValidInteger(strNumber, radix))
return parseInt(strNumber, radix);
return -1;
}
function isValidInteger(str, radix) {
var letters = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'].slice(0,radix);
str = str.toUpperCase();
for (var i=0; i<str.length; i++) {
var s = str.charAt(i);
if (letters.indexOf(s) == -1) return false;
}
return true;
}
function isValidRadix(radix) {
// 16 up to HEX system
return radix > 0 && radix <= 16;
}
console.log(convert("ASD", 15));
console.log(parseInt("ASD", 15));
console.log(convert("AAA", 15));
var x = 02345;
var y = x.toString();
alert(y);
I realized that there is a problem converting leading zeroes number to string in JavaScript using the toString() method.
As you can see from the output of the code above, the output is 1253 instead of the supposedly 02345.
If the leading zero is removed, the code will work as expected, why? What is happening with the code above so I can change it to work as expected.
var x = 2345;
var y = x.toString();
alert(y);
EDIT : The reason I asked this question is because I have two different codes that work differently despite being very similar. After reading that this question has nothing to do with the toString() method, why does the first set of code below not detect the number as an octal value but the second set of code does.
var num=window.prompt(); // num = 0012222
var str = num.toString();
var result = [str[0]];
for(var x=1; x<str.length; x++)
{
if((str[x-1]%2 === 0)&&(str[x]%2 === 0))
{
result.push('-', str[x]);
}
else
{
result.push(str[x]);
}
}
alert(result.join('')); //Outputs : 0-012-2-2-2
The other code :
function numberDash(num) {
var stringNumber = num.toString();
var output = [stringNumber[0]];
for (var i = 1; i < stringNumber.length; i++) {
if (stringNumber[i-1] % 2 === 0 && stringNumber[i] % 2 === 0) {
output.push('-', stringNumber[i]);
} else {
output.push(stringNumber[i]);
}
}
return output.join('');
}
numberDash(0012222) // Outputs : "52-6-6";
Many JavaScript engines add octal numeric literals to the specification. The leading zero indicates octal (base 8). 2345 in base 8 (octal) is 1253 in base 10 (decimal):
Octal Decimal
----- --------------------
2 2 * 8 * 8 * 8 = 1024
3 3 * 8 * 8 = 192
4 4 * 8 = 32
5 5
----- --------------------
2345 1253
You can disable that using strict mode. See §B.1.1 of the specification. Doing so makes 02345 a syntax error.
So it's nothing to do with toString, it's just that the 02345 in your code isn't the value you expect.
Re your updated question:
why does the first set of code below not detect the number as an octal value but the second set of code does
Because in the first code, you're not dealing with a number, you're dealing with a string. window.prompt returns a string, not a number, even if what you type in is all digits.
Even if you converted the string to a number via Number(num) or +num, the rules for runtime string->number conversion are different from the rules for parsing JavaScript source code.
var x = 02345;
var y = x.toString("8");
alert(y);
This will give you 2345
Leading zero is interpreted as octal value.
If you need number converted to string with leading zero, use my method but simply modify it like this var y = "0" + x.toString("8")
I store some parameters client-side in HTML and then need to compare them as integers. Unfortunately I have come across a serious bug that I cannot explain. The bug seems to be that my JS reads parameters as strings rather than integers, causing my integer comparisons to fail.
I have generated a small example of the error, which I also can't explain. The following returns 'true' when run:
console.log("2" > "10")
Parse the string into an integer using parseInt:
javascript:alert(parseInt("2", 10)>parseInt("10", 10))
Checking that strings are integers is separate to comparing if one is greater or lesser than another. You should always compare number with number and string with string as the algorithm for dealing with mixed types not easy to remember.
'00100' < '1' // true
as they are both strings so only the first zero of '00100' is compared to '1' and because it's charCode is lower, it evaluates as lower.
However:
'00100' < 1 // false
as the RHS is a number, the LHS is converted to number before the comparision.
A simple integer check is:
function isInt(n) {
return /^[+-]?\d+$/.test(n);
}
It doesn't matter if n is a number or integer, it will be converted to a string before the test.
If you really care about performance, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
return function(n) {
return re.test(n);
}
}());
Noting that numbers like 1.0 will return false. If you want to count such numbers as integers too, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
var re2 = /\.0+$/;
return function(n) {
return re.test((''+ n).replace(re2,''));
}
}());
Once that test is passed, converting to number for comparison can use a number of methods. I don't like parseInt() because it will truncate floats to make them look like ints, so all the following will be "equal":
parseInt(2.9) == parseInt('002',10) == parseInt('2wewe')
and so on.
Once numbers are tested as integers, you can use the unary + operator to convert them to numbers in the comparision:
if (isInt(a) && isInt(b)) {
if (+a < +b) {
// a and b are integers and a is less than b
}
}
Other methods are:
Number(a); // liked by some because it's clear what is happening
a * 1 // Not really obvious but it works, I don't like it
Comparing Numbers to String Equivalents Without Using parseInt
console.log(Number('2') > Number('10'));
console.log( ('2'/1) > ('10'/1) );
var item = { id: 998 }, id = '998';
var isEqual = (item.id.toString() === id.toString());
isEqual;
use parseInt and compare like below:
javascript:alert(parseInt("2")>parseInt("10"))
Always remember when we compare two strings.
the comparison happens on chacracter basis.
so '2' > '12' is true because the comparison will happen as
'2' > '1' and in alphabetical way '2' is always greater than '1' as unicode.
SO it will comeout true.
I hope this helps.
You can use Number() function also since it converts the object argument to a number that represents the object's value.
Eg: javascript:alert( Number("2") > Number("10"))
+ operator will coerce the string to a number.
console.log( +"2" > +"10" )
The answer is simple. Just divide string by 1.
Examples:
"2" > "10" - true
but
"2"/1 > "10"/1 - false
Also you can check if string value really is number:
!isNaN("1"/1) - true (number)
!isNaN("1a"/1) - false (string)
!isNaN("01"/1) - true (number)
!isNaN(" 1"/1) - true (number)
!isNaN(" 1abc"/1) - false (string)
But
!isNaN(""/1) - true (but string)
Solution
number !== "" && !isNaN(number/1)
The alert() wants to display a string, so it will interpret "2">"10" as a string.
Use the following:
var greater = parseInt("2") > parseInt("10");
alert("Is greater than? " + greater);
var less = parseInt("2") < parseInt("10");
alert("Is less than? " + less);
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)) ....