Weird unintentional rounding - javascript

I have an object value:
var myThingy = {
value: 10,
}
When I add/subtract complex integers (such as something with Math.PI) to value, it gets rounded (see snippet)! Why is this? What can I do to no get value rounded?
var myThingy = {
value: 10,
}
document.write(myThingy.value + "<p>");
myThingy.value--;
document.write(myThingy.value + "<p>");
myThingy.value - (45 / 360) * ( 2 * (Math.PI));
document.write(myThingy.value);

It isn't being rounded (at least, not back to an integer).
You've written an expression which reads the value of myThingy (although you actually want its value property), but you aren't doing anything with the result of evaluating that expression.
You need to assign the result back to the property before you look at it.
var myThingy = {
value: 10,
}
document.write(myThingy.value + "<p>");
myThingy.value--;
document.write(myThingy.value + "<p>");
myThingy.value = myThingy.value - (45 / 360) * ( 2 * (Math.PI));
document.write(myThingy.value);

myThingy - (45 / 360) * ( 2 * (Math.PI));
There is no = in this line. You are not re-assigning the result to myThingy in any way. Which is good, because you're attempting to subtract a number from an object.
So basically: pay attention to what you are doing, and to what each variable holds. It helps to give your variables meaningful names in this regard.

Related

Why does (-2.4492935982947064e-16).toFixed(5) equal "-0.00000"?

Given this code:
const value = 1;
Math.sin(2 * Math.PI * value).toFixed(5);
Why does this return "-0.00000", when the value before .toFixed(5) is -2.4492935982947064e-16?
The number is in scientific notation.
The e-16 means that there are 16 0's to the left of the number.
-2.4492935982947064e-16
is really
-0.00000000000000024492935982947064
When you run toFixed(5), you end up with 5 decimal places, which are all 0's.
The number you presented -2.4492935982947064e-16 is in scientific notation. That number would be equivalent to -2.4492935982947064 × 10^-16 which would be exactly -0.00000000000000024492935982947064 after expanding it.
-2.4492935982947064e-16 is -2.4492935982947064 * Math.pow(10,-16), so 5 places after decimal point is not enough to see something different than 0
const value = 1;
let result = Math.sin(2 * Math.PI * value);
console.log(result)
console.log(result.toFixed(20))
console.log(result.toFixed(5))

Javascript number comparison not correct

I'm doing some maths in javascript but I'm not getting the expected result all the time.
Here's my function - some parts have been simplified.
function updateExample($widget) {
var loan = parseInt($widget.attr("data-loan"), 10);
var term = parseInt($widget.attr("data-term"), 10);
// Get the best rate
var rateInfo = GetRateInfo(loan, term);
var annualRate = rateInfo[2];
// Calculate costs
var rate = (term === 1
? annualRate / 365 * 30
: annualRate / 12) / 100;
var pow = Math.pow(rate + 1, term);
var payment = round(rate * pow / (pow - 1) * loan, 2);
var totalRepayable = round(payment * term, 2);
var totalCostCap = round(loan * 2, 2);
var costCapped = false;
console.log(totalRepayable);
console.log(totalCostCap);
if (totalRepayable > totalCostCap) {
console.log("capped");
}
}
One of the tests that's failing is when I pass in a loan of 500 and a term of 1.
As you can see, I log 3 values to the console. The first 2 values output are:
620.00 and 1000.00
Given the values, I expect the following test to fail but it doesn't.
if (totalRepayable > totalCostCap)
if (620.00 > 1000.00)
The console log reads "capped" to prove the if statement has been entered.
I'm not a javascript expert by any means but I can't see how this is failing.
Here's the custom round function:
function round(value, decimals) {
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals).toFixed(decimals);
}
Any advice appreciated.
You don't show your round function, but I'm assuming it's using .toFixed(). The problem is you don't actually have arbitrary precision floating point numbers, so it converts to string, and
console.log("620.00" > "1000.00"); // true
The thing that tipped me off is that if you log a number like 620.00 to the console it automatically truncates it, the fact that you were seeing trailing zeros suggests it's a string.
Update
Yeah, now that you posted that it's definitely returning a string. The last part of the return value is a call to .toFixed(). Just cast the result back to a number to do the comparison.

Values are wildly off in JS

So I am calculating values, snapshotting them and send them into a interval. But the issue is, is its wildly increasing what the sum should be.
Here is the calculations:
// Set up mob attributes - SNAPSHOT
const mobId = '1';
var mob = {
mhp: (mobId + 10) * 15,
hp: (mobId + 10) * 15,
dmg: (mobId + 2) * 3,
defenseRating: (mobId + 3) * 4,
hitRating: (mobId + 2) * 2,
critRating: (mobId + 3) * 2,
critDmg: (mobId + 2) * 2,
dodgeRating: (mobId + 1) * 3,
firstHitRating: (mobId + 3) * 4,
};
console.log(mob);
I don't know about you, but in what world does 11 * 15 = 1650. This is the calculations BEFORE I send it through the interval, so it isn't messing up there. It is the intial calculations that being very weird.
Note: It may be worth noting that I am doing this through a socket event:
socket.on('fight mob', (mobId) => {
I doubt that is the issue but I am at a loss right now.
This is happening because your mobId variable is a string, not a number.
(1 + 10) * 15 = 165
("1" + 10) * 15 = 1650
To resolve this, you can coerce mobId's type using Number():
(Number(mobId) + 10) * 15 = 165
Good luck!
Due to loose typing, JavaScript automatically tries to change the types of variables when performing operations on them. In your case, mobId is a string and not a number. So, instead of addition, JavaScript performs concatenation.
So the operation
(mobId + 10) * 15
becomes something like this for mobId being '1':
'110' * 15
Again, JavaScript's type caster kicks in, but this time it converts the string to number for multiplication, so the result becomes 1650.
To mitigate, convert the mobId to number first. Use parseInt or parseFloat for that:
mobId = parseInt(mobId, 10);
(mobId + 10) * 15 // Yields 165

How might I use answers.length to select any one entry from an array?

I have an array called answers, and it's length is 20. So Math.floor(Math.random() * answers.length); is equivalent to Math.floor(Math.random() * 20); I would like to randomly select any ONE of those 20 entries in the array, which means I'd like 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 to be the possible numbers to be selected; so every entry can be selected. Would that mean I should use Math.floor(Math.random() * answers.length) + 1; ? Ultimately, my question is asking whether or not it makes a difference if I add "+ 1".
For example: https://jsfiddle.net/Henry7720/v96Lj4aw/ (without the 1) https://jsfiddle.net/Henry7720/v96Lj4aw/1/ (with the 1)
To convert Math.random() to an integer within a certain range, you would use Math.floor(Math.random() * (max - min) + min). Note that this will pick any number that is at least min but less than max. Because min is 0, those values can just be taken out, so to get a value from an array, use:
var item = array[Math.floor(Math.random() * array.length)];
Edit: also, adding the one would simply offset the index by one. This means it would never select value 0 and have a one in array.length to pick a value outside of the bounds of the array, returning undefined.
The examples you gave are actually ignoring the values inside the array. Using something like the following would let you select a random value regardless of the values inside it:
var randomAnswer = answers[Math.floor(Math.random() * answers.length)]
Then it would work for answer arrays like:
[2, 4, 6, 8]
["Matt", "Daniel", "Steve"]
and so on.
You can use this function.
Simply provide min and max value on function call,and function will return random value in range of arguments you provided.
function rng(min,max) {
var rng = Math.round(min - 0.5 + Math.random() * (max - min + 1));
return rng;
}
answers[rng(0,answers.length -1)];

JavaScript math calculation

I need to perform a math calculation in JavaScript that I am unsure how to do so.
The formula is as follows:
result = (scale * weighting) / 2
where the result I will need to two decimal places.
Example formula that I need to do in JavaScript might be:
result = ((3 * 2) + (2 * 1.5)) / 2
I am also unsure if I have to also convert this to int.
toFixed:
function algorithm(scale, weighting) {
var result = (scale * weighting) / 2;
return result.toFixed(2);
}
Or if you need an integer, parseInt:
parseInt(result, 10);
Not entirely sure what you want, but this might help:
result = Math.round(((scale * weighting) / 2) * 100) / 100;
http://jsfiddle.net/kQpma/
In JavaScript everything number is a floating point number. No explicit type conversion needed.
ref : http://oreilly.com/javascript/excerpts/learning-javascript/javascript-datatypes-variables.html ( search for "The Number Data Type" )

Categories