Reputation: 13
function obliczTo() {
var bet = document.forms["oblicz"]["bet"].value;
var kol = document.forms["oblicz"]["kolejki"].value;
var bankRoll = bet * Math.pow(2.1, kol)
document.write('Potrzebujesz: ' + Math.ceil(bankRoll))
}
<form name="oblicz" onsubmit="return obliczTo()" method="post" required>
Bet: <input type="text" name="bet"> Ile kolejek: <input type="text" name="kolejki">
<input type="submit" value="Submit">
</form>
I want to print every power in html and add all of them together and print that as bankRoll. for ex
bet = 10
kol = 5
in html:
21
44.1
92.61
194.481
408.4101
Bank Roll: 760.6011
And I want to print each individual output and show their accumulated sum as "Bank Roll".
Upvotes: 1
Views: 188
Reputation: 28206
By using the geometric series summation formula you can simplify your algorithm in the way that you can directly calculate the sum of any series without having to step through the individual exponentiation steps:
where S
is the total sum, a
is the starting amount, q
is the factor and n
the highest exponent. I modified the formula here slightly: I subtracted the initial amount a
from it, as you don't seem to want it included in the summation. So you end up with this modified summation formula:
const geomSum=([a,q,n])=>// (a*(q**(n+1)-1)/(q-1)-a).toFixed((n||6)-1),
(a*(q**(n+1)-q)/(q-1) ).toFixed((n||6)-1),
res=document.getElementById('res'),
v=[].slice.call(document.querySelectorAll('input'));
function calc(){res.textContent=geomSum(v.map(e=>+e.value));}
document.querySelector('form').oninput=calc;
calc();
<form>
<input name="a" placeholder="start value" value="10"><br>
<input type="number" name="q" placeholder="factor" value="2.1"><br>
<input type="number" name="n" placeholder="exponent" value="5">
</form><br><br>
<div id="res"></div>
Upvotes: 1
Reputation: 5926
First off, note that JavaScript numbers are floating point, and floating-point arithmetic with fractions is often imprecise. For example:
Math.pow(2.1, 4)
// should be 19.4481
// actually yields 19.448100000000004
Math.ceil
rounds up to the nearest integer, which won't work for what we want here - Math.ceil(19.448100000000004)
gives 20
.
Here's one (kinda hacky) way of dealing with it that should work for our use case, as long as kol
doesn't get very high:
const round = n => Number(n.toPrecision(12))
Now, you need to loop through numbers 1..kol
, printing and summing as you go. You can use a for
loop for this.
const form = document.forms.oblicz
const output = document.querySelector('#output')
const round = n => Number(n.toPrecision(12))
const clearOutput = () => output.textContent = ''
const appendLineToOutput = str => output.textContent += `\n${str}`
form.addEventListener('submit', e => {
e.preventDefault()
clearOutput()
const bet = Number(form.bet.value)
const kol = Number(form.kolejki.value)
let bankRoll = 0
for (let i = 1; i <= kol; ++i) {
const val = round(bet * Math.pow(2.1, i))
appendLineToOutput(val)
bankRoll = round(bankRoll + val)
}
appendLineToOutput(`Potrzebujesz: ${bankRoll}`)
})
<form name="oblicz" required>
Bet: <input type="text" name="bet" value="10"> Ile kolejek: <input type="text" name="kolejki" value="5">
<input type="submit" value="Submit">
</form>
<pre><output id="output"></output></pre>
Note that I've used document.querySelector
and textContent
here, not document.write
. document.write
is generally considered to be deprecated, because it clears the entire document if the page is already loaded.
Upvotes: 0