why the odd results adding floats in javascript? - javascript

I have javascript code like this:
var strikePrice = parseFloat(this.props.data.strike).toFixed(1);
var commission = parseFloat(this.props.commission / 100).toFixed(2);
var callInMoney = parseFloat(strikePrice + this.state.callPrice + commission).toFixed(2);
var putInMoney = parseFloat(strikePrice - this.state.putPrice - commission).toFixed(2);
console.log("strikePrice: " + strikePrice + " commission: " + commission);
console.log("callprice: " + this.state.callPrice + " putprice: " + this.state.putPrice);
console.log("call: " + callInMoney + " put: " + putInMoney);
and the output is this:
strikePrice: 34.0 commission: 0.08
callprice: 0 putprice: 0
call: 34.00 put: 33.92
That is wrong. The call should be 34.08 (8 cents higher) just like the put is 8 cents lower.
Why is the results not correct?
Thank you
Matt

toFixed returns a string so you're actually doing some string concatenation rather than the arithmetic you expect.
Check out what happens when you just print out your initial addition.
var strikePrice = parseFloat('34').toFixed(1);
var commission = parseFloat('0.08').toFixed(2);
console.log(strikePrice + 0 + commission);
Instead, you'll need to convert those strings to numbers first.
var strikePrice = parseFloat('34').toFixed(1);
var commission = parseFloat('0.08').toFixed(2);
strikePrice = parseFloat(strikePrice);
commission = parseFloat(commission);
console.log(strikePrice + 0 + commission);

This expression:
strikePrice + this.state.callPrice + commission
Evaluates to this value:
"34.000.08"
Because commission is a string value, which is because [toFixed()][1] takes an integer and returns a string.
You need to refactor your code so that commission is a float value, or so that you call parseFloat() again on the parameters of line 3.
I can't comment on why putInMoney works for you. For me it gave "NaN".

Related

javascript numbers assignment

i'm having some issues with the final two console.logs of my script. i'm supposed to have numbers output for both but i'm getting NAN
alert("Let's make a shopping list!");
let first = prompt("What is the first item?");
let firstCost = Number(prompt("What is the cost of " + first + "?"));
let firstAmount = Number(prompt("How many of " + first + " would you like?"));
let second = prompt("What is the second item?");
let secondCost = Number(prompt("What is the cost of " + second + "?"));
let secondAmount = Number(prompt("How many of " + second + " would you like?"));
let tax = parseInt(prompt("What is the sales tax for your state?"));
let firstTotal = parseFloat(firstCost * firstAmount);
let secondTotal = parseFloat(firstCost * firstAmount);
let subTotal = parseFloat(firstTotal + secondTotal);
let taxTotal = parseFloat(subTotal * tax);
let grandTotal = parseFloat(subTotal + taxTotal);
console.log(first + " " + firstCost + " " + firstAmount + " " +
firstTotal);
console.log(second + " " + secondCost + " " + secondAmount + " " +
secondTotal);
console.log("tax: " + taxTotal);
console.log("TOTAL: " + grandTotal);
I changed all of the Number() to parseFloat() but I'm not getting the outcome I'm looking for.
Error 1. Copy/paste
This line of code is a mistake:
let secondTotal = parseFloat(firstCost * firstAmount);
You have copied-and-pasted, without changing "first" to "second".
Error 2. You haven't decided whether tax is a percentage or a decimal fraction
You are collecting an INTEGER, i.e. 5% tax will be stored as 5.
But you are using it as though it is a fraction (e.g. 5% represented as 0.05), by just multiplying it by subtotal.
Error 3. When entering data you are using 'cancel' to skip the tax value
This causes it to store NaN in the tax, and that messes up all output that depends on the tax.
Tip. To get answers quickly, get rid of all the code that is irrelevant, and make it runnable within Stack Overflow, using the "<>" icon.
That helps people help you.
let firstCost = Number(prompt("What is the cost of first ?"));
let firstAmount = Number(prompt("How many of first would you like?"));
let secondCost = Number(prompt("What is the cost of second?"));
let secondAmount = Number(prompt("How many of second would you like?"));
// In this next line you are storing an integer (e.g. 5, for 5 percent)
let tax = parseInt(prompt("What is the sales tax for your state?"));
let firstTotal = parseFloat(firstCost * firstAmount);
// This next line is a mistake
// let secondTotal = parseFloat(firstCost * firstAmount);
// You meant this:
let secondTotal = parseFloat(secondCost * secondAmount);
let subTotal = parseFloat(firstTotal + secondTotal);
// But in this line you are treating it as though it is a decimal, e.g. 0.05 for 5 percent.
// let taxTotal = parseFloat(subTotal * tax);
// You probably meant this:
let taxTotal = parseFloat(subTotal * tax/100);
let grandTotal = parseFloat(subTotal + taxTotal);
console.log("tax: " + taxTotal);
console.log("TOTAL: " + grandTotal);

why javascript show string all arithmetic operation?

as you show below, when javascript doing an arithmetic operation all value concatenation with the string it shows a string value but I have some confusion...
var x = 10;
var y = 20;
var sum = x + y;
console.log("sum is :" + sum); //this is number
But confusion is
var x = 10;
var y = 20;
console.log("sum is : " + 10 + 20 ); //why this is string
var x = 10;
var y = "The value is " + x; // why this is string
var x = 10;
var y = 20;
var sum = x + y;
var z = 'sum is' + sum; //why this string
console.log("sum is : " + sum) // why this is not string coz it is also concatenation with string.
JavaScript will concatenate and coerce in a certain order of operations. You can add parentheses to add numbers before coercing to a string.
console.log("sum is : " + 10 + 20); // sum is : 1020
console.log("sum is : " + (10 + 20)); // sum is : 30
The unary + operator can be used to convert a variable to a number:
var y = "5"; // y is a string
var x = + y; // x is a number
If the variable cannot be converted, it will still become a number, but with the value NaN (Not a Number):
var y = "John"; // y is a string
var x = + y; // x is a number (NaN)
When JavaScript tries to operate on a "wrong" data type, it will try to convert the value to a "right" type.
5 + null // returns 5 because null is converted to 0
"5" + null // returns "5null" because null is converted to "null"
"5" + 2 // returns "52" because 2 is converted to "2"
"5" - 2 // returns 3 because "5" is converted to 5
"5" * "2" // returns 10 because "5" and "2" are converted to 5 and 2
So if you put numbers inside parenthesis like (10 + 20) then it will perform arithmetic operation first then it will do the concatenation outside. If either one of them would be string then it would do the concatenation inside as well.
var console.log("sum is : " + (10 + 20) ); // sum is : 30
var console.log("sum is : " + (10 + '20') ); // sum is : 1020
When you are adding a number with a string it counts the number as a string, like console.log("sum is : " + 10 + 20 ).
But when 10 and 20 is under a variable it counts the number as a variable value.
If you want to use numbers with a string use "sum is: " + parseInt(10) like this.

Converted Int returns NaN

Here is my code
var fifty = prompt("Enter amount ");
var twenty;
alert(twenty=parseInt(fifty/50) + " x " + "50 dollar bill");
alert(parseInt(twenty/20) + " x " + "20 dollar bill");
What I'm trying to count is dollar bills.
For example when I enter "120" it should return 2x 50 bills and 1x 20 dollar bill, I understand that returned value is String type so I'm converting them number, but on 20 dollar bills it returns "Nan x 20 dollar bils" I'm having trouble understanding why
Please stop using parseInt for separating integer part of float value, use it only to convert string into integer. When you are using parseInt float value is converted into string and than some integer number is parsed back, there can be situation when float number will be converted in string like 5.1234E-6 and parseInt will return 5 in this case. Use Math.floor() instead.
var sum = parseInt(prompt("Enter amount "));
var twenty = Math.floor(sum/50);
alert(twenty + " x " + "50 dollar bill");
alert(Math.floor((sum - (twenty*50))/20) + " x " + "20 dollar bill");
I've shuffled around your variable names to make it a bit clearer.
// I'll use the example of 120 to demonstrate
// The total amount, e.g. 120
var amount = prompt("Enter amount ");
// First, convert the inputted string into an int
var amountAsInt = parseInt(amount, 10);
// Then, divide by 50 (which equals 2.4), and then use
// Math.floor() to "chop off" the decimal part
var numberOfFifties = Math.floor(amountAsInt/50);
// Leaving us with numberOfFifties = 2
// We can now use 'modulus' to give the amount left.
// If you haven't come across modulus before, it gives
// the remainder after dividing by the given number (here: 50)
var amountLeft = amount % 50;
// Do the same with the amount left to find the number of 20s
var numberOfTwenties = Math.floor(amountLeft / 20);
if(numberOfFifties > 0){alert(numberOfFifties + " x " + "50 dollar bill(s)");}
if(numberOfTwenties > 0){alert(numberOfTwenties + " x " + "20 dollar bill(s)");}
JSFiddle here:
http://jsfiddle.net/7p57e3u1/3/
Reason for the NaN
You can see the reason why you were getting an NaN by looking at this JSFiddle.
http://jsfiddle.net/pto52oe5/
You are setting twenty to be equal to the whole string, hence it is "Not a Number" (NaN).
alert(twenty=parseInt(fifty/50) + " x " + "50 dollar bill");
Here, you appear to be assuming that
twenty=parseInt(fifty/50)
will be treated as a separate "part", but in actual fact, it uses the whole expression, setting twenty to be the whole string that is output in the alert():
twenty = parseInt(fifty / 50) + " x " + "50 dollar bill"
i.e. (for the example above)
twenty = "2 x 50 dollar bill"
A useful technique for debugging (and creating more understandable and therefore maintainable code) is to split things down into very simple steps, as I have in the example code above. This (arguably) is broken down too far, but use that as a first technique to break down a problem like this.
You have a problem in your logic.
Maybe something like that:
http://jsfiddle.net/2e7cs06v/
var total = prompt("Enter amount ");
var numOf50=parseInt(total/50);
var moneyLeft = total - (numOf50 * 50);
alert(numOf50 + " x " + "50 dollar bill");
alert(parseInt(moneyLeft/20) + " x " + "20 dollar bill");
Note that I'm not trying to fix the algorithm here, but just the input errors and type.
You should first parse fifty to an int, then only divide it by 50, since you want an int even after dividing by 50 you can let the initial parseInt.
Also, be aware that parseInt needs a radix (10 here), and it may still return NaN if a non parseable value is given.
var fifty = parseInt(prompt("Enter amount "), 10);
alert(twenty=parseInt(fifty/50, 10) + " x " + "50 dollar bill");
As an alternative, you could use the bitwise or (|) which acts almoste like parseInt(x, 10) except that when it would have returned NaN with parseInt, it would return 0 with the bitwise or operator.
Using |
var fifty = prompt("Enter amount ") | 0;
alert(twenty=((fifty/50)|0) + " x " + "50 dollar bill");
Use following :
var fifty = prompt("Enter amount ");
var twenty;
twenty=parseInt(fifty/50);
var rem = fifty - (twenty * 50);
alert(twenty + " x " + "50 dollar bill");
alert(parseInt(rem/20) + " x " + "20 dollar bill");
Hope it will help !!
Because you have parsing more string (+ " x " + "50 dollar bill") into parseInt() function. So parseInt function not able to pars "dollar bill" text value.
var fifty = prompt("Enter amount ");
var twenty = parseInt(fifty/50);
alert( twenty + " x " + "50 dollar bill");
alert(parseInt(twenty/20) + " x " + "20 dollar bill");

Add two values together in Mootools

My Javascript / Mootools knowledge is limited, so I am having trouble figuring out how to take the following code and make it produce a sum and assign the value to the ordertotal variable.
$('ordertotal').value = '$' + 100 * $('tickets').value + 10 * $('fiftytickets').value + '.00';
The tickets variable is either 1 or 2 depending on the user selection and the fiftytickets variable is either 0.5, 2.5 or 5.0 depending of the user selection. Both variables are supplied values using a HTML select menu and they function correctly when used individually.
For example:
$('ordertotal').value = '$' + 100 * $('tickets').value + '.00';
Works correctly and
$('ordertotal').value = '$' + 10 * $('fiftytickets').value + '.00';
Works correctly, but I can figure out how to add them together and assign them to the ordertotal variable.
Any assistance with this issue would be greatly appreciated.
Thank you.
Mike
Seems like you are trying to get sum of string + int + int + string
Your two examples worked, because there was only concatenation (string + int(converted to string) + string)
And when you add a nubmer to a "$" - your number get converted to a string. What you can do is to either put numbers sum in () or get the value separately:
sumValue = 100 * $('tickets').value + 10 * $('fiftytickets').value
$('ordertotal').value = '$' + sumValue + '.00';
Example:
> "1" + 1
"11"
> "$" + 1 + ".00"
"$1.00"
> "$" + 1 + 1 + ".00"
"$11.00"
> "$" + (1 + 1) + ".00"
"$2.00"

Why I got NaN in this javaScript code?

First I test that every variable got a number value:
09-11 18:15:00.420:
d_drop: -1.178791867393647
drop_at_zero: 0.0731037475605623
sightHeight: 4.5
d_distance: 40
zeroRange: 10
09-11 18:15:00.420:
d_drop: true
drop_at_zero: true
sightHeight: true
d_distance: true
zeroRange: true
function isNumber (o) {
return ! isNaN (o-0) && o != null;
}
var d_drop; // in calculation this gets value 1.1789
var d_path = -d_drop - sightHeight + (drop_at_zero + sightHeight) * d_distance / zeroRange;
console.log("Path: " + d_path + " cm");
and in the log:
09-11 18:15:00.430: D/CordovaLog(1533): Path: NaN cm
WHY? I have tried to figure that out couple of hours now and no success, maybe someone has an idea, I haven't!
Thanks!
Sami
-------ANSWER IS that parse every variable when using + operand-----------
var d_path = parseFloat(-d_drop) - parseFloat(sightHeight) + (parseFloat(drop_at_zero) + parseFloat(sightHeight)) * parseFloat(d_distance) / parseFloat(zeroRange);
The addition operator + will cast things as strings if either operand is a string. You need to parse ALL of your inputs (d_drop, sightHeight, etc) as numbers before working with them.
Here's a demo of how the + overload works. Notice how the subtraction operator - is not overloaded and will always cast the operands to numbers:
var numberA = 1;
var numberB = 2;
var stringA = '3';
var stringB = '4';
numberA + numberB // 3 (number)
numberA - numberB // -1 (number)
stringA + stringB // "34" (string)
stringA - stringB // -1 (number)
numberA + stringB // "14" (string)
numberA - stringB // -3 (number)
http://jsfiddle.net/jbabey/abwhd/
At least one of your numbers is a string. sightHeight is the most likely culprit, as it would concatenate with drop_at_zero to produce a "number" with two decimal points - such a "number" is not a number, hence NaN.
Solution: use parseFloat(varname) to convert to numbers.
If you're using -d_drop as a variable name, that is probably the culprit. Variables must start with a letter.
var d_drop = -1.178791867393647,
drop_at_zero = 0.0731037475605623,
sightHeight = 4.5,
d_distance = 40,
zeroRange = 10;
var d_path = d_drop - sightHeight + (drop_at_zero + sightHeight) * d_distance / zeroRange;
console.log("Path: " + d_path + " cm"); // outputs: Path: 12.613623122848603 cm

Categories

Resources