I'm sorry I know this is probably not a smart question but it's driving me crazy. Given this recursive function, why is 1 not returned all the time? I mean, eventually the exponent will get to 0!
function power(base, exponent) {
if (exponent == 0)
return 1;
else
return base * power(base, exponent - 1);
}
Thanks so much for any help.
The best way to understand is to walk through the code. Let's say you do power(2,3).
What does that do?
2 * power(2,2)
//Which expands to
2 * 2 * power(2,1)
//Which expands to
2 * 2 * 2 * power(2,0)
//Which expands to
2 * 2 * 2 * 1
When 1 is returned, it is not returned to the original function call, but just the most recent function call. Every time the power function calls itself, it puts a new invocation of itself on the stack. So for instance if we call power(2, 1), that will call power(2, 0). power(2, 0) will return its value of 1 to where it was called in power(2, 1). Then power(2, 1) will return base * power(base, exponent - 1); which is base * 1 which is 2.
This may best be understood by contrasting your recursive power function with a very similar function that does always return the value 1.
function one(base, exponent) {
if (exponent == 0)
return 1;
else
return one(base, exponent - 1);
}
Notice that the only difference between your power function and one is that the the recursive call to one is the value being returned in the recursive case.
In your power function, the value being returned is base multiplied with the value of the recursive call. Thus each recursive call to power contributes to the value ultimately being returned by the initial call; whereas, only the final call to one (when exponent is 0) contributes to the returned value.
Let's assume we call power(2, 5) [i.e. with base=2 and exponent=5].
It will evaluate in the following way:
power(2, 5) = ...
Hmmm... Let's calculate power(2, 5). Is exponent==0? No it isn't (it's 5). Then we return base*power(base, exponent-1), which actually means 2*power(2,4).
power(2, 5) = 2 * power(2, 4)
= 2 * ?
Hmmm... Let's calculate power(2, 4). Is exponent==0? No it isn't (it's 4). Then we return base*power(base, exponent-1), which actually means 2*power(2,3).
power(2, 5) = 2 * power(2, 4)
= 2 * (2 * power(2, 3))
= 2 * (2 * ?)
Hmmm... Let's calculate power(2, 3). Is exponent==0? No it isn't (it's 3). Then we return base*power(base, exponent-1), which actually means 2*power(2,2).
power(2, 5) = 2 * power(2, 4)
= 2 * (2 * power(2, 3))
= 2 * (2 * (2 * power(2, 2)))
= 2 * (2 * (2 * ?))
Hmmm... Let's calculate power(2, 2). Is exponent==0? No it isn't (it's 2). Then we return base*power(base, exponent-1), which actually means 2*power(2,1).
power(2, 5) = 2 * power(2, 4)
= 2 * (2 * power(2, 3))
= 2 * (2 * (2 * power(2, 2)))
= 2 * (2 * (2 * (2 * power(2, 1))))
= 2 * (2 * (2 * (2 * ?)))
Hmmm... Let's calculate power(2, 1). Is exponent==0? No it isn't (it's 1). Then we return base*power(base, exponent-1), which actually means 2*power(2,0).
power(2, 5) = 2 * power(2, 4)
= 2 * (2 * power(2, 3))
= 2 * (2 * (2 * power(2, 2)))
= 2 * (2 * (2 * (2 * power(2, 1))))
= 2 * (2 * (2 * (2 * (2 * power(2, 0)))))
= 2 * (2 * (2 * (2 * (2 * ?))))
Hmmm... Let's calculate power(2, 0). Is exponent==0? Yes, it is! Then we return 1.
power(2, 5) = 2 * power(2, 4)
= 2 * (2 * power(2, 3))
= 2 * (2 * (2 * power(2, 2)))
= 2 * (2 * (2 * (2 * power(2, 1))))
= 2 * (2 * (2 * (2 * (2 * power(2, 0)))))
= 2 * (2 * (2 * (2 * (2 * 1))))
= 2 * (2 * (2 * (2 * 2)))
= 2 * (2 * (2 * 4))
= 2 * (2 * 8)
= 2 * 16
= 32
Post Scriptum: You should understand that return <something> specifies result value of the innermost (i.e. the latest) function call (not the outermost, i.e. the oldest).
Because it is the result of multiplying the base by itself a certain number of times, which is how exponents work. Because base is being multiplied by power(base, exponent - 1) (and power(base, exponent - 1) itself is not being returned), each iteration where exponent is not 0 essentially adds another multiplication of the base onto the result.
As an aside, this is not a very good power function.
Related
I am trying to get a result that looks like this
"The volume of the cone 261.66 is greater than the volume of the cylinder 785: false."
console.log("The volume of the cone " +(10 / 3 * (3.14 * (5 **2))) "is greater than the volume of the cylinder " +(10 * (3.14 * (5 **2)))): 261 > 785);
EDIT: Thanks for all your help everyone. I can believe I didn't see that I didn't put + and thanks for point out ":" I was so tired and I just wanted to finish I can't believe I wasted all that time getting the math to work just to miss a + and forgot about :
You missed adding + or concatenation after the numerical expressions and : should have been in quotes too as its a string. Better yet use templating, both examples below:
// With concatination
console.log("The volume of the cone " + (10 / 3 * (3.14 * (5 ** 2))) + " is greater than the volume of the cylinder " + (10 * (3.14 * (5 ** 2))) + ": " + (261 > 785));
// With templating
console.log(`The volume of the cone ${(10 / 3 * (3.14 * (5 ** 2)))} is greater than the volume of the cylinder ${(10 * (3.14 * (5 ** 2)))}: ${(261 > 785)}`);
You missed a + and ":"
With template literals
console.log(`The volume of the cone ${(10 / 3 * (3.14 * (5 **2)))} is greater than the volume of the cylinder ${(10 * (3.14 * (5 **2)))} : ${261 > 785}`);
Template literals
It should be one from below
String Concatenation
console.log("The volume of the cone " + (10 / 3 * (3.14 * (5 **2))) + "is greater than the volume of the cylinder " + (10 * (3.14 * (5 **2))) + ":" + (261 > 785));
Please Note the importance of the paranthesis in (261 > 785). Removing the bracket will throw a false as output. Because the string expression in console will be checked against > 785 if the bracket is removed, that will result in false as result
OR
Template Literals
console.log(`The volume of the cone ${(10 / 3 * (3.14 * (5 **2)))} is greater than the volume of the cylinder ${(10 * (3.14 * (5 **2)))} : ${261 > 785}`);
This question already has answers here:
How to round to at most 2 decimal places, if necessary
(91 answers)
Closed 6 years ago.
How to get following inputs to bellow outputs
Input
1.0789
10.350
1.7777
Output
1.07
10.35
1.77
Use Math.floor to round the decimal places under the current value.
Reference
Example
Math.floor(1.0789 * 100) / 100
Working Fiddle
console.log(Math.floor(1.0789 * 100) / 100);
console.log(Math.floor(10.350 * 100) / 100);
console.log(Math.floor(1.7777 * 100) / 100);
console.log(Math.floor(12.34 * 100) / 100);
you have several methods for do this
Use Math.round(num * 100) / 100
Use Math.ceil(num * 100)/100;
This question already has answers here:
Explain Math.floor(Math.random())
(6 answers)
Closed 7 years ago.
Is this the most efficient way of randomly generating 0 or 1 in javascript?
Math.floor(Math.random() * 2);
No, Math.random() * 2 | 0 and Math.random() * 2 << 0 seem to be (marginally) faster in most browsers, which makes sense since it has one less function invocation from the Math library.
Faster alternatives:
(Math.random() * 2) | 0
~~ (Math.random() * 2)
(Math.random() * 2) << 0
I have this code in JavaScript:
SolarPanels = parseInt(lRemainingWidth / (panel_width + ( 2 * lPanelInterSpace)));
and then I alert the SolarPanels value which gives NaN as output,
alert("SolarPanels "+SolarPanels);
This 1 line is a tiny part of a huge calculation, but my code seems to fail here,
with the use of alerts i've read out the values of SolarPanels, lRemainingWidth, panel_width and lPanelInterSpace
which are the following:
lRemainingwidth = 17.4.320227272727276
SolarPanels = 0
panel_width = 1.65
lPanelInterSpace = 0.02
I think it has to do with the 2 dots in lRemainingWidth, either way, I don't know how to fix it. Why the lRemainingWidth has 2 dots?
Update :
This is the part that calculates the lRemainingWidth :
if(HalforDouble === "Yes")
{
lRemainingWidth = (roof_ridge /2) + ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge);
}
else
{
lRemainingWidth = roof_ridge + (2 * ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge));
}
The values here are:
lRemainingWidth = 0
roof_ridge = 17
lRemainingHeight = 20.769000000000002
lRoofEdgeDegrees = 83.5169263071276
lRoofEdge = 0.2
Your problem is that you mix strings and numbers
Start with this code before any computation :
var roof_ridge = parseFloat(roof_ridge);
There might be other strings hidden in your code but we don't see them. Apply the same conversion on them.
lRemainingWidth = roof_ridge + (2 * ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge));
If roof_ridge is a string then the + does string concatenation instead of addition.
Change this to
lRemainingWidth = +roof_ridge + (2 * ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge));
The prefix + operator in +roof_ridge coerces its argument to a number.
It seems like a cornerstone of the issue in roof_ridge variable. This variable is instance of String class, not a number. So, when you code go to this line:
lRemainingWidth = roof_ridge + (2 * ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge));
the next calculation is done:
'17' + whatever_float_value = got string concatenation instead of number's sum.
To fix this just add:
lRemainingWidth = parseFloat(roof_ridge) + (2 * ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge));
The Formula looks like this:
(25000 x (.06 / 12)) / (1 - ((1 + (.06 / 12))^(-36))) = 760.548436
I have been attempting to convert this to javascript but with not much luck. If you put that above formula into google you will see the answer.
After many attempts and different methods, braking up the formula into different variables then dividing them, I haven't had any luck, when I came up with this, it got me the wrong answer:
var loan = 25000;
var rate = 6 / 100;
var term = 36;
var calculate = (loan * (rate / 12)) / (1 - ((1 + (rate / 12))^(-term)));
console.log(calculate);
Output was:
3.4722222222222223
And not 760.548436. Anyone have any ideas?
The caret is a bitwise operator. You want this formula instead:
calculate = (loan * (rate / 12)) / (1 - Math.pow(1 + (rate / 12), -term));
It gives you the answer you expect, 760.5484362888927