JavaScript: Logical Comparison fails when values have different decimal places - javascript

The code below is the beginning of a program that will allow the user to input values and the computer will guess the values. I'm stuck on my input validation. For some reason my input validation passes when I compare numbers with the same decimal places, such as 25 and 49.
Image of passed input validation
However, when I try to compare something like 9 and 25, although the input validation should allow it through, it goes to the else portion of my code. I assume this has something to do with the way JavaScript is interpreting the data type. The code is a bit messy and the program is not complete. The focus is just on the way I'm pulling the values from the HTML and the input validation now. Here's the code.
function runGame() {
//get variables from the input fields in HTML form
var low = document.getElementById('lowNum').value;
var high = document.getElementById('highNum').value;
var guess = document.getElementById('compGuess').value;
//input validation
if (low < high && low > 0 && high <= 50 && guess > 0 && guess <= 10) {
alert("Low number: " + low + "\nHigh Number: " + high + "\nComputer Guesses: " + guess);
document.getElementById("computerGuessVal").innerHTML = getRndInteger(low, high);
} else {
alert("Invalid selection. Make sure that the number range is between 1 and 50 and guesses are higher than zero.");
}
}
function getRndInteger(low, high) {
high = Math.floor(high);
low = Math.ceil(low);
return Math.floor(Math.random() * (high - low + 1)) + low;
}

Update - Solved I added ParseInt to my code after checking the data types
with alert(typeof guess). Here's the working code:
//get variables from the input fields in HTML form and convert to integer
var low = parseInt(document.getElementById('lowNum').value);
var high = parseInt(document.getElementById('highNum').value);
var guess = parseInt(document.getElementById('compGuess').value);
Thanks for the suggestions!

Related

Why do we need parseInt() with a variable [duplicate]

This question already has answers here:
Why is typeof x never 'number' when x comes from the prompt function?
(4 answers)
Closed 5 years ago.
See code below. My question is, why do I need to use parseInt() on bill and tipPercent for the totalCost calculation when the use actually enters in an integer already?
function billTotal() {
var bill = prompt("How much was your meal?");
if (bill != parseInt(bill)) {
alert("You need to enter an integer");
return;
};
var tip = prompt("How much would you like to tip?");
if (tip != parseInt(tip)) {
alert("You need to enter a number");
return;
}
var tipPercent = bill * (tip / 100);
var totalCost = parseInt(bill) + parseInt(tipPercent);
alert("You're Meal Cost " + totalCost);
};
billTotal();
The result of window.prompt is always a string. You need to use parseInt if you want to work with it as an integer.
Please note that result is a string. That means you should sometimes cast the value given by the user. For example, if his answer should be a Number, you should cast the value to Number. var aNumber = Number(window.prompt("Type a number", ""));
Reference : https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt
Usually, you need parseInt in order to convert a user input (prompt) to an integer and then does arithmetic operations using this value.
As it stated more formally here:
The parseInt() function parses a string argument and returns an
integer of the specified radix (the base in mathematical numeral
systems).
Your code could be refactored like below. Initially we parse the user input and provided that input is valid we proceed with the calculation.
function billTotal() {
var billStr = prompt("How much was your meal?");
var bill = parseInt(billStr,10);
if (!bill || bill < 0) {
alert("You entered an ivalid value for bill");
return;
};
var tipStr = prompt("How much would you like to tip?");
var tip = parseInt(tipStr,10);
if (!tip || tip < 0) {
alert("You entered an invalid value for tip");
return;
};
var tipPercent = bill * (tip / 100);
var totalCost = bill + tipPercent;
alert("You're Meal Cost " + totalCost);
};
billTotal();

Make Dynamic Calculations from Keyboard Input with JavaScript?

I need a simple calculation script that will take number values entered into an input field and display results dynamically based on predefined set of criteria.
For example, I have a set of fee criteria as follows:
0-150 = No charge
150-300 = Display only fixed monthly fee
300-2500 = multiply by 0.002 + fixed monthly fee - 300 = amount
enter amount more than 2500 = multiply by 0.0015 + fixed monthly fee - 300 = amount
I need the results displayed dynamically as the user is typing in the input, without pressing a button. I want to use JavaScript/jQuery for this.
How can this be done? I find it hard to set up the code. Please, help me out with directions and examples. Or better yet, guide me to the solution that will work as described. Can this be done?
I appreciate your help much and thank you all brave coders taking on this challenge! :)
Got it. So the function is as follows:
function calResult(n){
var fixedMonthlyFee = 9.95;
if(0 <= n && n <= 150){
jQuery("#desc").text("No charge");
}else if(150 <= n && n <= 300) {
jQuery("#desc").text(fixedMonthlyFee);
} else if(300 <= n && n <= 2500) {
jQuery("#desc").text(n * 0.002 * 30 + fixedMonthlyFee);
} else {
jQuery("#desc").text(n * 0.0015 * 30 + fixedMonthlyFee);
}
}
console.log('--No Erros--');
Hope that will be helpful to others!

RegEx for range between 1-999999 and precision upto 2 decimal places

I trying trying to apply RegEx in JavaScript that will allow user to enter ammount of min 1 and max 999999 and if user want to enter ammount in decimal then it will allow user to enter decimal upto precision of 2.
Below are the inputs with their respective result
100: Pass
999999: Pass
100.23: Pass
100.2: Pass
100.234: Fail
This is what I have tried so far ^([1-9][0-9]{0,2}|999999)$), this allow me to enter the amount within 1-999999 but I also want to handle decimal cases.
Maybe this could work?:
^[1-9]\d{0,5}(?:\.\d{1,2})?$
I'd recommend doing it logically;
[0, 0.75, 100, 999999, 999999.75, 100.23, 100.2, 100.234].forEach(i => {
var inRange = i >= 1 && i <= 999999; // check whether in range 1-999999
var inPrecisionRange = i * 100 % 1 == 0; //check whether has at most 2 dec. point
console.log(i + " -> " + (inRange && inPrecisionRange));
});
Much simpler, easier to read and much more maintainable than RegEx IMO

Amex & CC Formatting Javascript - Lets settle this once and for all

I am trying to format credit cards as users type them into the field. I've read every topic on the subject here on stack overflow, looked at tons of sites, lots of libraries and the code behind them. I want to create a simple function that will format credit cards as the user types them into the field using VANILLA JAVASCRIPT. Some of the following code comes from topics found here on Stack Overflow but none of the threads have solved the particular problem of doing this as the user is typing into the field.
PROBLEM: By default as the user is typing the into the given credit card field it changes the value by putting spaces in between the numbers, it will not validate as an American Express card until all the digits have been entered and thus not adjust the format until it is complete. I've tried casting the value without spaces and retesting it every cycle but to no avail.
function cc_format(v) {
//Strip the field value of spaces.
amextest = v.replace(/\s/g, '');
//Test if the card is an american express each cycle
if(/3[47]\d{2}[ -]*\d{6}[ -]*\d{5}/.test(amextest))
{
//This is some borrowed code to format american express cards - http://stackoverflow.com/questions/27322733/javascript-regex-format-string-containing-american-express-card-number
v.replace(/\b(\d{4})(\d{6})(\d{5})\b/, '$1-$2-$3');
return v;
}
else
{
//This properly formats every other card type as its being typed.
var v = v.replace(/[^\d]/g, '').match(/.{1,4}/g);
return v ? v.join(' ') : '';
}
}
//This binds the function to an input
document.getElementById('credit_card').oninput = function() {
this.value = cc_format(this.value)
}
I call upon the gods of stack overflow, please help me put this rest once and for all!
EDIT: Forgot the OP wanted plain JS. I'll leave this here for posterity, but it is obviously not an answer.
You could try this - match on the first two digits, and then automatically update the input after the 4th digit (and prevent an input greater than 17 characters (15 digits and 2 dashes):
$('#cc').on('keyup', function() {
var amexTest = $(this).val().replace(/ /g, '');
if (amexTest.match(/^3[47]\d{2}/)) {
if (amexTest.length == 4) {
amexTest += '-';
$('#cc').val(amexTest);
}
if (amexTest.length == 11) {
amexTest += '-';
$('#cc').val(amexTest);
}
if (amexTest.length > 17) {
val = $(this).val().substr(0, $(this).val().length - 1);
$(this).val(val);
}
} else {
if (amexTest.length > 16) {
val = $(this).val().substr(0, $(this).val().length - 1);
$(this).val(val);
}
if (amexTest.length == 16) {
var splits = amexTest.match(/\d{4}/g);
val = splits.join(' ');
$(this).val(val);
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="cc">

Javascript Money Calculations (Inconsistent Results)

I am currently trying to calculate fees that my service charges for sales (8%). The seller can input the amount they want to receive, or want's the buyer to pay (Like Steam does here: http://i.imgur.com/pLFN9px.png). I am currently using this code:
function precise_round(num, decimals) {
var t=Math.pow(10, decimals);
return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}
var elem = $(this);
elem.data('oldVal', elem.val());
elem.bind("propertychange change click keyup input paste", function(event){
if (elem.data('oldVal') != elem.val()) {
elem.data('oldVal', elem.val());
if(elem.attr("id")=="seller-gets") {
var cur = elem.val();
var value = cur*1.08;
$("#buyer-pays").val(precise_round(value), 2);
} else {
var cur = elem.val();
var value = cur*0.92;
$("#seller-gets").val(precise_round(value), 2);
}
}
});
});
The Receive(Left) <--> Pay(Right) conversions are not consistent. (Putting the same number the left produced back into the right gives a different left).
Sorry if this is not clear enough, I can explain it a little better if needed.
Those are inconsistent before you are doing two different things. Say for eg. lets take 5 as the left number.
8% of 5 = .4, So Right number will be 5.4
And if you put 5.4 as the right number 8% of it is .432 not .4. So the left number will be 5.4 - .432 = 4.968 and not 5.
If you want to get back the same number then you have to multiply by 1.08 for left -> right conversion and divide by 1.08 for the vice-versa.
Hope this helps.
Firstly, can you be sure that the values that are passed to the precise_round function are what you expect?
If not, then I think from looking at your code that you need to convert the raw values to float. I have had the same problem with values being one cent wrong, and converting to float fixed it.
var value = cur*1.08;
should be:
var value = parseFloat(cur)*1.08;
and
var value = cur*0.92;
should be:
var value = parseFloat(cur)*0.92;
After that, you can use value.toFixed(2) instead of rounding. Something to try anyway.

Categories