Why does same javascript code give different result? [duplicate] - javascript

This question already has answers here:
How to add two strings as if they were numbers? [duplicate]
(20 answers)
Closed last year.
I am a beginner at javascript. I find following piece of code a bit difficult for me. I think both are same, and should have give the same result. But they are throwing different result.
var a = 5,
b = 6,
c = 7;
if (a + b > c || b + c > a || a + c > b) {
let s = (a + b + c) / 2;
let area = Math.sqrt(s * ((s - a) * (s - b) * (s - c)));
console.log(`The area of the triangle is: ${area}`);
} else {
console.log('Triangle does not exist');
}
It gives me a result. But when i try to take input from user and input the same value (5,6,7), find different result.
var a = prompt(),
b = prompt(),
c = prompt();
if (a + b > c || b + c > a || a + c > b) {
let s = (a + b + c) / 2;
let area = Math.sqrt(s * ((s - a) * (s - b) * (s - c)));
console.log(`The area of the triangle is: ${area}`);
} else {
console.log('Triangle does not exist');
}
Maybe I am wrong. But I just want know the reason.
Thanks.

My assumption is that this is related to prompt() returning a string and not an integer. Therefore the additions of the variables a, b and c would concatenate the strings and only after that - caused by the comparison > and after division / - convert it to a number. So in order to fix this, I think using parseInt() to parse the numbers returned from prompt() would fix the issue

The promt causes the variables to be defined as a string and as #Barmar pointed out in his comment, this changes the behavior of the '+' operation in your if-statement.
With numbers 1 +1 is returned as 2, with strings 11.
What you can do is change the following:
let s = (a + b + c) / 2;will give you 567/2 as you have strings.
let s = (parseInt(a) + parseInt(b) + parseInt(c) ) / 2; will give you the desired result as the method parseInt() returns a intger value.

Related

Function/Do-while to generate random numbers until they are all the same

(Javascript) My goal is to generate 3 random numbers assigned to a,b, and c. I want to do this over and over until a b and c all are the same number while also keeping track of how many tries it takes. However, the only outcome is my "Error" part that I have added for debugging. Any ideas on where I possibly went wrong?
var a = Math.floor(Math.random() * 6) + 1;
var b = Math.floor(Math.random() * 6) + 1;
var c = Math.floor(Math.random() * 6) + 1;
var runs = 0;
function tripleNumbers() {
while(a!=b && c !=b) {
a = Math.floor(Math.random() * 6) + 1;
b = Math.floor(Math.random() * 6) + 1;
c = Math.floor(Math.random() * 6) + 1;
runs++;
}
if(a == b && a == c) {
document.write("A: "+a);
document.write("B: "+b);
document.write("C: "+c);
document.write("Total Runs: "+runs);
}
else {
document.write("Error");
}
}
tripleNumbers();
In the while loop, you have to use an OR operator (||) instead of AND, because you want to run the loop until either of the inequalities is true:
while(a!=b || c!=b){/*...*/}
Or negate the entire expression, and use positive equality checks:
while(!(a==b && c==b)){/*...*/}
while(a!=b && c !=b) {
The issue is that your logic is being short circuited. a != b && c != b says that you should perform the loop so long as both those conditionals are true.
However, if the first conditional is false, the second one is not evaluated.
So, logically, the most we can assert after that conditional ends is that a == b.
If you want to make sure the loop continues so long as any of the values are different, you should change it to use an OR. That way, for the loop to end, it has to be true that a == b and c == b.

What am I doing wrong with this RGB to HSV colour conversion equation?

For a uni project I am making my own RGB to HSV colour converter.
Here is the code I have written
function calcSat() {
s = (maxRGB() - minRGB()) / maxRGB();
if (isNaN(s)) {
s = 0;
}
}
function calcVal() {
v = maxRGB();
}
function calcHue() {
var dr = (maxRGB() - r) /
maxRGB() - minRGB();
dr = Math.abs(dr);
var dg = (maxRGB() - g) /
maxRGB() - minRGB();
dg = Math.abs(dg);
var db = (maxRGB() - b) /
maxRGB() - minRGB();
db = Math.abs(db);
console.log("red:" + r, "green:" + g, "blue:" + b);
console.log("red d:" + dr, "green d:" + dg, "blue d:" + db);
if (s == 0) {
h = 0;
} else if (r == maxRGB && g == minRGB) {
h = 5 + db;
} else if (r == maxRGB && g != minRGB) {
h = 1 - dg;
} else if (g == maxRGB && b == minRGB) {
h = dr + 1;
} else if (g == maxRGB && b != minRGB) {
h = 3 - db;
} else if (r == maxRGB) {
h = 3 + dg;
} else {
h = 5 - dr;
}
h = h * 60;
}
You can also access a copy of the project here: https://editor.p5js.org/eeu8cc/sketches/tYfnkWrA-
Essentially, I am trying to create 3 functions to calculate the Hue, Saturation and Value of an RGB colour. Everything runs fine but my output is completely wrong.
As far as I can tell I have reproduced the equation correctly.
Here is the equation to that I am trying to re-write in code:
For those interested, the screenshots came from a PDF that can be found here.
Any help would be greatly appreciated.
Why are you taking absolute values for dr,dg,db? Not that there should be any way for these to go negative, and in fact if they do I would be taking that as indicating a bug further up.
I am a C and VHDL man rather then javascript, but surely
if (r == maxRGB && g == minRGB)
should rather be something like
if (r == maxRGB() && g == minRGB())?
I am assuming that == & && bind the right ways and that you don't need extra braces (I would put them in in C just because it has some obscure cases that are not worth remembering).
I also question the wisdom of floating point equality comparisons here, that seldom ends well. It would be ok, if not great design in a fixed point type but IIRC javascript tends to use FP for any numeric stuff which is just painful (And X86 does excess precision if there is not a register flush involved, which can sting with FP equalities). See Goldburgs classic paper if you want to get your math on, or this if you want something simpler https://floating-point-gui.de/
Should not maxRGB and minRGB be taking arguments (You don't show these functions) but I would expect them to take r,g,b as parameters?
I tend to deal with colour in broadcast (where we live in Y'CbCr spaces), but I also think you should probably be converting to a linear light space before doing your conversion as otherwise the gamma curves will screw you, but this is a nicety.

Can't get BBP formula to work in nodejs

I've been trying to make a little program that can compute the n-th digit of pi.
After a few searches I've found that the most common formula is the BBP formula, wich is n-th digit = 16^-n[4/(8n + 1)-2/(8n + 4)-1/(8n + 5)-1/(8n + 6)].
The output is in base 16.
My code is the following:
function run(n) {
return Math.pow(16, -n) * (4 / (8 * n + 1) - 2 / (8 * n + 4) - 1 / (8 * n + 5) - 1 / (8 * n + 6));
}
function convertFromBaseToBase(str, fromBase, toBase) {
var num = parseInt(str, fromBase);
return num.toString(toBase);
}
for (var i = 0; i < 10; i++) {
var a = run(i);
console.log(convertFromBaseToBase(a, 16, 10));
}
So far, my output is the following:
1:3
2:0
3:0
4:0
5:1
6:7
7:3
8:1
9:7
10:3
Obviously, these are not the 10 first digits of PI.
My understanding is that values get rounded too often and that causes huge innacuracy in the final result.
However, I could be wrong, that's why I'm here to ask if I did anything wrong or if it's nodejs's fault. So I would loove if one of you guys have the answer to my problem!
Thanks!!
Unfortunately, 4/(8n + 1) - 2/(8n + 4) - 1/(8n + 5) - 1/(8n + 6) does not directly return the Nth hexadecimal digit of pi. I don't blame you, I made the same assumption at first. Although all the terms do indeed sum to pi, each individual term does not represent an individual hexadecimal digit. As seen here, the algorithm must be rewritten slightly in order to function correctly as a "digit spigot". Here is what your new run implementation ought to look like:
/**
Bailey-Borwein-Plouffe digit-extraction algorithm for pi
<https://en.wikipedia.org/wiki/Bailey%E2%80%93Borwein%E2%80%93Plouffe_formula#BBP_digit-extraction_algorithm_for_.CF.80>
*/
function run(n) {
var partial = function(d, c) {
var sum = 0;
// Left sum
var k;
for (k = 0; k <= d - 1; k++) {
sum += (Math.pow(16, d - 1 - k) % (8 * k + c)) / (8 * k + c);
}
// Right sum. This converges fast...
var prev = undefined;
for(k = d; sum !== prev; k++) {
prev = sum;
sum += Math.pow(16, d - 1 - k) / (8 * k + c);
}
return sum;
};
/**
JavaScript's modulus operator gives the wrong
result for negative numbers. E.g. `-2.9 % 1`
returns -0.9, the correct result is 0.1.
*/
var mod1 = function(x) {
return x < 0 ? 1 - (-x % 1) : x % 1;
};
var s = 0;
s += 4 * partial(n, 1);
s += -2 * partial(n, 4);
s += -1 * partial(n, 5);
s += -1 * partial(n, 6);
s = mod1(s);
return Math.floor(s * 16);
}
// Pi in hex is 3.243f6a8885a308d313198a2e037073...
console.log(run(0) === 3); // 0th hexadecimal digit of pi is the leading 3
console.log(run(1) === 2);
console.log(run(2) === 4);
console.log(run(3) === 3);
console.log(run(4) === 15); // i.e. "F"
Additionally, your convertFromBaseToBase function is more complicated than it needs to be. You have written it to accept a string in a specific base, but it is already being passed a number (which has no specific base). All you should really need is:
for (var i = 0; i < 10; i++) {
var a = run(i);
console.log(a.toString(16));
}
Output:
3
2
4
3
f
6
a
8
8
8
I have tested this code for the first 30 hexadecimal digits of pi, but it might start to return inaccurate results once Math.pow(16, d - 1 - k) grows beyond Number.MAX_SAFE_INTEGER, or maybe earlier for other reasons. At that point you may need to implement the modular exponentiation technique suggested in the Wikipedia article.

Project Euler Solution 9 Code Not Working

function getAnswer(){
var answer, c = 334;
while (c < 999){
var a = Math.round(((1000 - c) / 2) - 0.5), b = Math.round((1000 - c) / 2);
while (a > 0 && b < c){
if (Math.pow(a, 2) + Math.pow(b, 2) != Math.pow(c, 2)){
a -= 1;
b += 1;
}else{
answer = a * b * c;
}
}
c += 1;
}
document.getElementById("a").innerHTML = answer;
}
Hi! I am a beginner programmer in javascript, and I have been trying to solve problem 9 in Project Euler. That problem goes like this:
A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
a^2 + b^2 = c^2
For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
I don't know why no answer appears, and my script crashes/program stops running, whenever I run this script. Please explain and tell me what's wrong with my script.
When you have found the answer, you don't stop with the iteration. Even worse, you don't change the values of a and b any more, so they never reach the end of the iteration, and you're stuck in an infinite loop.
You'll need to break out of the loop when you've found the answer. Or even break out of both your nested loops, using a label:
function getAnswer() {
var answer,
c = 334;
find: while (c < 999) {
var a = Math.round(((1000 - c) / 2) - 0.5),
b = Math.round((1000 - c) / 2);
while (a > 0 && b < c) {
if (Math.pow(a, 2) + Math.pow(b, 2) == Math.pow(c, 2)) {
answer = a * b * c;
break find;
}
a -= 1;
b += 1;
}
c += 1;
}
document.getElementById("a").innerHTML = answer;
}
Notice that it would be easier if your function just returned the answer, instead of populating #a with it. You'd call it like
document.getElementById("a").innerHTML = getAnswer();
and can just return a * b * c; to break out of the whole function.

Weird addition with javascript in internet explorer

I'm having an issue in Internet Explorer 8, it's not computing addition of three variables in javascript?
I have this:
var y = function(s) {
var p = ($.browser.msie || $.browser.opera) ? h(s) : s.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
delete p[0];
var r = ((p[1] / 255) * 0.2989);
var g = ((p[2] / 255) * 0.5180);
var b = ((p[3] / 255) * 0.1140);
return (r + g + b);
};
Now, this is working in Chrome, Opera, and Firefox but not Internet Explorer, IE is giving me NaN. It's working if I just use return (r + g) or return (g + b)
I have tried return ((r + g) + b) and I have tried var rg = (r + g); return (rg + b);
But I keep getting NaN. Is there some special trick to adding three variables in javascript with IE???
I'd first try running isNaN() against each of the variables r,g and b to ensure that the value of each is in fact numeric. If so, perhaps try adding them together and assigning the result to a variable that you then return.

Categories

Resources