C# Loop för att räkna ut ränta-på-ränta effekt

Permalänk

C# Loop för att räkna ut ränta-på-ränta effekt

För år 1 blir det ju rätt, men följande år ska ju blir ett större tal. Men nu får jag samma summa varje gång.

Behöver jag säga att jag är helt ny på detta

using System; namespace Uträkning { class MainClass { public static void Main(string[] args) { int avkastning = 0; int pengar = 0; int year = 0; int total = 0; int konto = 0; Console.Write("Hur mycket vill du spara per månad: "); string strPengar = Console.ReadLine(); pengar = int.Parse(strPengar); Console.Write("Hur många år är ditt mål: "); string strYear = Console.ReadLine(); year = int.Parse(strYear); Console.Write("Vilken avkastning räknar du med: "); string strAvkastning = Console.ReadLine(); avkastning = int.Parse(strAvkastning); Console.WriteLine(pengar + " per månad, i " + year + " år med " + avkastning + "% avkastning"); for (int i = 1; i <= year; i++) { total = konto + pengar * 12 + (pengar * 12 * avkastning / 100); Console.WriteLine("Efter " + year + " år är totalen: " + total); total = konto; } } } }

Permalänk
Hedersmedlem

Fundera över hur ränta på ränta funkar, titta sedan på formeln du har som räknar ut summan.
Ett förslag kan vara att du tänker dig att du sätter in pengarna på ett konto och varje år så ökar du kontot med avkastningen.

Visa signatur

Använd gilla för att markera nyttiga inlägg!

Permalänk
Medlem

Du sparar över totalen varje iteration istället för att lägga till på den. Testa att stega igenom programmet och kolla vilka värden dina variabler har så kommer du enkelt upptäcka vad som är fel.

Permalänk
Medlem

Är totalen verkligen rätt? Som det är nu får du väl samma ränta på pengarna som sparades i januari som i december. Du borde inte få samma ränta på de olika besparingarna.

Permalänk
Skrivet av m1ken:

Du sparar över totalen varje iteration istället för att lägga till på den. Testa att stega igenom programmet och kolla vilka värden dina variabler har så kommer du enkelt upptäcka vad som är fel.

Jag sitter med Visual Basic Community, på en mac, och jag vet inte ens hur jag stegar igenom koden, rad för rad. Har sett på klipp hur det görs på en windows-maskin.

Permalänk
Skrivet av giplet:

Fundera över hur ränta på ränta funkar, titta sedan på formeln du har som räknar ut summan.
Ett förslag kan vara att du tänker dig att du sätter in pengarna på ett konto och varje år så ökar du kontot med avkastningen.

Behöver jag ytterligare en variabel för kontot då? Har provat, men får det inte att fungera. Står lite stilla i hjärnkontoret nu

Har justerat koden i första inlägget.

Permalänk
Medlem

@beachroadsix:
Menar du Visual Studio Community?

Sätt en breakpoint på raden du vill att koden ska stanna, förslagsvis i innan programmet går in i loopen. Sen kör du koden så kommer den att stanna på breakpointen. Sen kör du Step Over (f10) eller step into (f11) för att stega. När koden står still kan du hovra över en variabel för att se värdet.

Permalänk
Medlem

Om du inte får till debuggen kan du alltid fundera på din formel med papper och penna.

Säg att jag skriver i 1000 kronor i månader, över 10 år med 10 % avkastning.

total = 1000 * 12 + (1200) = 13200.
Sen skriver du ut att det blev 13200.

Sen loopar du, utan att spara undan dessa 13200 någonstans. Vilket gör att du bara sparar över totalen och får 13200 igen.
Du har lagt till ett konto vilket är rimligt, men som du gör du kommer det alltid att vara noll.

Permalänk
Medlem
Skrivet av beachroadsix:

Jag sitter med Visual Basic Community, på en mac, och jag vet inte ens hur jag stegar igenom koden, rad för rad. Har sett på klipp hur det görs på en windows-maskin.

Jag antar att du menade Visual Studio, men debugging borde fungera ungefär lika oavsett vilken version av Visual Studio du har. D.v.s. sätt en brytpunkt på någon rad i koden genom att klicka i marginalen till vänster om koden. Kör sedan programmet med debugging påslaget (brukar vara standard), debuggern kommer då pausa programmet på den raden. Därefter kan du inspektera variablernas värden, stega rad för rad, fortsätta köra till nästa brytpunkt, etc.

Jag rekommenderar dig starkt att lägga lite tid på att klura ut hur debuggern fungerar, det kommer vara oerhört hjälpsamt för dig att kunna se exakt vad som händer när din kod körs.

Permalänk
Hedersmedlem
Skrivet av beachroadsix:

Behöver jag ytterligare en variabel för kontot då? Har provat, men får det inte att fungera. Står lite stilla i hjärnkontoret nu

Har justerat koden i första inlägget.

Tanken med detta forumet är inte att ge folk svar på skoluppgifter. Du måste tänka själv.
Skriv ner på papper hur du vill att det ska funka. Utgå ifrån att pengar sätts in på ett konto. Sedan skriver du koden som utför hur du tänker dig att det ska funka. Om du själv har skrivit koden som du postar så har du tillräcklig kunskap för att lösa problemet.

Visa signatur

Använd gilla för att markera nyttiga inlägg!

Permalänk
Skrivet av giplet:

Tanken med detta forumet är inte att ge folk svar på skoluppgifter. Du måste tänka själv.
Skriv ner på papper hur du vill att det ska funka. Utgå ifrån att pengar sätts in på ett konto. Sedan skriver du koden som utför hur du tänker dig att det ska funka. Om du själv har skrivit koden som du postar så har du tillräcklig kunskap för att lösa problemet.

Detta är ingen skoluppgift, är en uppgift som jag själv vill göra, för att efterlikna de som finns färdiga på diverse aktie-siter.
Började att koda vid årsskiftet, försöker lära mig de olika looparna, vilken som passar till vad.
Metoder suger jag på totalt, men har förstått att det är fina grejer.
De första raderna är ju ganska basic, men kör ihop sig när det gäller for-loopen. Finns säkert bättre sätt att lösa uppgiften på.
Jag vet hur det ska fungera, men jag får inte till adderingen i loopen, så att när varv två börjar, så ska den använda totalen från varv ett.

Permalänk
Skrivet av perost:

Jag antar att du menade Visual Studio, men debugging borde fungera ungefär lika oavsett vilken version av Visual Studio du har. D.v.s. sätt en brytpunkt på någon rad i koden genom att klicka i marginalen till vänster om koden. Kör sedan programmet med debugging påslaget (brukar vara standard), debuggern kommer då pausa programmet på den raden. Därefter kan du inspektera variablernas värden, stega rad för rad, fortsätta köra till nästa brytpunkt, etc.

Jag rekommenderar dig starkt att lägga lite tid på att klura ut hur debuggern fungerar, det kommer vara oerhört hjälpsamt för dig att kunna se exakt vad som händer när din kod körs.

Självklart menar jag Visual Studio
Tack för tipset, får helt enkelt sätta mig in i det. Har inte riktigt förstått det än, utan har lagt in diverse console.write här och där för att läsa ut nuvarande värde. Men blir väldigt plottrig kod, och känns begränsat

Permalänk
Medlem

Ett litet men stort problem i din kod just nu, är att dina beräkningar förutsätter decimaltal, men dina variabeltyper är heltal.

Till exempel: avkastning deklarerar du i början av Main att vara en int.

... public static void Main(string[] args) ... int avkastning = 0; ...

int är kort för "integer", i.e. heltal. Vilken typ ett värde är av bestämmer vilken slags operation som kommer utföras när man använder operatorer som + och /. Du kommer få oväntat resultat på en senare rad där du gör avkastning / 100. Eftersom avkastning är ett heltal, så kommer heltalsdivision utföras. Säg att din räntesats är 5%, då har är avkastning = 5, och då medför heltalsdivision att avkastning / 100 = 5 / 100 = 0, eftersom heltalsdivision avrundar resultatet ned till heltalet. Så där du förväntar dig 0.05, så får du 0. För att testa detta skulle du kunna ändra din WriteLine-rad att också printa resultatet av avkastning/100.

En lösning är att du använder flyttalstypen double istället för int, vilken kan representera decimaltal till viss precision. För ett amatör/hobbysystem så är detta lätt den bästa lösningen.

Kuriosa: I verkliga finanssystem så undviker man oftast flyttalstyper som double, eftersom de har begränsad precision. Istället används lösningar baserade på heltal och fraktioner av heltal. Sådana implementationer är dock mer avancerade, och är inget du bör kika på innan du kan mer.

EDIT: Mitt svar gäller fortfarande i allmänhet, men är kanske faktiskt inte vad du har problem med just nu. Detta då precedens och associativitet av operatorerna i C# medför att ditt uttryck pengar * 12 * avkastning / 100 beräknas som ((pengar * 12) * avkastning) / 100. Det vill säga, det beräknas från vänster till höger, så talet som delas med 100 är i de flesta fall nog mycket större än 100, så medan betydlig avrundning fortfarande sker (inte bra!), så är det inte alls lika stort fel som om den gick från höger till vänster och beräknade avkastning / 100 först!

Visa signatur

Arbets- / Spelstation: Arch Linux - Ryzen 5 3600 - RX 7900 XT - 32G DDR4
Server: Arch Linux - Core i5-10400F - 16G DDR4

Permalänk
Skrivet av m1ken:

Om du inte får till debuggen kan du alltid fundera på din formel med papper och penna.

Säg att jag skriver i 1000 kronor i månader, över 10 år med 10 % avkastning.

total = 1000 * 12 + (1200) = 13200.
Sen skriver du ut att det blev 13200.

Sen loopar du, utan att spara undan dessa 13200 någonstans. Vilket gör att du bara sparar över totalen och får 13200 igen.
Du har lagt till ett konto vilket är rimligt, men som du gör du kommer det alltid att vara noll.

Verkar som om jag fått till det, men kanske inte på smidigaste sätt?

Skrivet av Bryal:

Ett litet men stort problem i din kod just nu, är att dina beräkningar förutsätter decimaltal, men dina variabeltyper är heltal.

Till exempel: avkastning deklarerar du i början av Main att vara en int.

... public static void Main(string[] args) ... int avkastning = 0; ...

int är kort för "integer", i.e. heltal. Vilken typ ett värde är av bestämmer vilken slags operation som kommer utföras när man använder operatorer som + och /. Du kommer få oväntat resultat på en senare rad där du gör avkastning / 100. Eftersom avkastning är ett heltal, så kommer heltalsdivision utföras. Säg att din räntesats är 5%, då har är avkastning = 5, och då medför heltalsdivision att avkastning / 100 = 5 / 100 = 0, eftersom heltalsdivision avrundar resultatet ned till heltalet. Så där du förväntar dig 0.05, så får du 0. För att testa detta skulle du kunna ändra din WriteLine-rad att också printa resultatet av avkastning/100.

En lösning är att du använder flyttalstypen double istället för int, vilken kan representera decimaltal till viss precision. För ett amatör/hobbysystem så är detta lätt den bästa lösningen.

Kuriosa: I verkliga finanssystem så undviker man oftast flyttalstyper som double, eftersom de har begränsad precision. Istället används lösningar baserade på heltal och fraktioner av heltal. Sådana implementationer är dock mer avancerade, och är inget du bör kika på innan du kan mer.

EDIT: Mitt svar gäller fortfarande i allmänhet, men är kanske faktiskt inte vad du har problem med just nu. Detta då precedens och associativitet av operatorerna i C# medför att ditt uttryck pengar * 12 * avkastning / 100 beräknas som ((pengar * 12) * avkastning) / 100. Det vill säga, det beräknas från vänster till höger, så talet som delas med 100 är i de flesta fall nog mycket större än 100, så medan betydlig avrundning fortfarande sker (inte bra!), så är det inte alls lika stort fel som om den gick från höger till vänster och beräknade avkastning / 100 först!

Tack för tipset. Provade att göra om avkastningen till double, men tydligen går det inte att använda double och int i samma formel. Finns säkert en lösning på det, men dit har inte jag kommit än.

Uppdaterad kod nedan, kommentarer tas gärna emot.

using System; namespace Uträkning { class MainClass { public static void Main(string[] args) { int avkastPro = 0; int summaAr = 0; int year = 0; int konto = 0; int total = 0; Console.Write("Hur mycket vill du spara per månad: "); string strPengar = Console.ReadLine(); summaAr = int.Parse(strPengar); summaAr = summaAr * 12; Console.Write("Hur många år är ditt mål: "); string strYear = Console.ReadLine(); year = int.Parse(strYear); Console.Write("Vilken avkastning räknar du med: "); string strAvkastning = Console.ReadLine(); avkastPro = int.Parse(strAvkastning); Console.WriteLine((summaAr/12) + " per månad, i " + year + " år med " + avkastPro + "% avkastning"); for (int i = 1; i <= year; i++) { total = konto + (konto * avkastPro / 100) + summaAr + (summaAr * avkastPro / 100); Console.WriteLine("Efter " + i + " år är totalen: " + total); konto = total; } } } }

Permalänk
Medlem
Skrivet av beachroadsix:

Verkar som om jag fått till det, men kanske inte på smidigaste sätt?

Tack för tipset. Provade att göra om avkastningen till double, men tydligen går det inte att använda double och int i samma formel. Finns säkert en lösning på det, men dit har inte jag kommit än.

Uppdaterad kod nedan, kommentarer tas gärna emot.

using System; namespace Uträkning { class MainClass { public static void Main(string[] args) { int avkastPro = 0; int summaAr = 0; int year = 0; int konto = 0; int total = 0; Console.Write("Hur mycket vill du spara per månad: "); string strPengar = Console.ReadLine(); summaAr = int.Parse(strPengar); summaAr = summaAr * 12; Console.Write("Hur många år är ditt mål: "); string strYear = Console.ReadLine(); year = int.Parse(strYear); Console.Write("Vilken avkastning räknar du med: "); string strAvkastning = Console.ReadLine(); avkastPro = int.Parse(strAvkastning); Console.WriteLine((summaAr/12) + " per månad, i " + year + " år med " + avkastPro + "% avkastning"); for (int i = 1; i <= year; i++) { total = konto + (konto * avkastPro / 100) + summaAr + (summaAr * avkastPro / 100); Console.WriteLine("Efter " + i + " år är totalen: " + total); konto = total; } } } }

När man hanterar pengar ska man använda sig av decimal, den har bäst precision och är skapad för att just hantera pengar.

Till din fråga, ska du räkna int och double i samma sats så måste du casta om din int som en double vid beräkningen.
Nackdelen att göra dessa beräkningar med ints är att int alltid avrundar nedåt och bara klipper av alla decimaltal, något som kan ha enorma konsekvenser gällande t.ex. ränta på ränta.
Får du ett tal t.ex 231.99 så kommer int skriva 231. Så tar i princip bort en krona där.

Skickades från m.sweclockers.com

Permalänk
99:e percentilen

Vad är syftet med variablerna total och konto? Försök beskriva utförligt och tydligt vad var och en av dem är tänkt att representera.

Visa signatur

Skrivet med hjälp av Better SweClockers

Permalänk
Skrivet av Alling:

Vad är syftet med variablerna total och konto? Försök beskriva utförligt och tydligt vad var och en av dem är tänkt att representera.

Konto innehåller totalsumman från föregående år.
Första året så blir ju den bara 0.

Hade jag inte haft konto så hade det sett ut så här till exempel
5000 per månad
3 år
4% avkastning

60000 + 2400 (12 x 5000 + 4%)
120000 + 4800
180000 + 7200

Vill ju att det ska se ut så är

60000 + 2400
122400 + 4896
187296 + 7491

Kanske inte bästa förklaringen men hoppas den går hem

Permalänk
Medlem

Feltänk av mig *hjärnsläpp*

Permalänk
Hedersmedlem
Skrivet av beachroadsix:

Konto innehåller totalsumman från föregående år.
Första året så blir ju den bara 0.

Hade jag inte haft konto så hade det sett ut så här till exempel
5000 per månad
3 år
4% avkastning

60000 + 2400 (12 x 5000 + 4%)
120000 + 4800
180000 + 7200

Vill ju att det ska se ut så är

60000 + 2400
122400 + 4896
187296 + 7491

Kanske inte bästa förklaringen men hoppas den går hem

Men det du egentligen vill är väl:
0 + 60000 + 2400
62400 + 60000 + 4896
Dvs ingående behållning plus instättningar plus ränta.

Visa signatur

Använd gilla för att markera nyttiga inlägg!

Permalänk
Skrivet av giplet:

Men det du egentligen vill är väl:
0 + 60000 + 2400
62400 + 60000 + 4896
Dvs ingående behållning plus instättningar plus ränta.

Är väl så jag skrev, men jag skrev summan av 62400 + 60000 istället, var lite lat, borde vara mer tydlig

Permalänk
Medlem
Skrivet av beachroadsix:

Konto innehåller totalsumman från föregående år.

Om konto innehåller totalsumman, vad innehåller då variabeln total? Fundera på om det kanske inte är onödigt att ha båda de variablerna för att hålla reda på hur mycket pengar som finns på kontot.

Permalänk
Skrivet av perost:

Om konto innehåller totalsumman, vad innehåller då variabeln total? Fundera på om det kanske inte är onödigt att ha båda de variablerna för att hålla reda på hur mycket pengar som finns på kontot.

Tyckte jag hade provat alla möjliga varianter förut, men fick det inte att fungera. Så öppnade koden igen, och testade en sak, och vips, så fungerade det. Men var kanske inte den lösningen du hade tänkte dig? Tack

using System; namespace Uträkning { class MainClass { public static void Main(string[] args) { int avkastPro = 0; int summaAr = 0; int year = 0; int konto = 0; Console.Write("Hur mycket vill du spara per månad: "); string strPengar = Console.ReadLine(); summaAr = int.Parse(strPengar); summaAr = summaAr * 12; Console.Write("Hur många år är ditt mål: "); string strYear = Console.ReadLine(); year = int.Parse(strYear); Console.Write("Vilken avkastning räknar du med: "); string strAvkastning = Console.ReadLine(); avkastPro = int.Parse(strAvkastning); Console.WriteLine((summaAr/12) + " per månad, i " + year + " år med " + avkastPro + "% avkastning"); for (int i = 1; i <= year; i++) { konto = konto + (konto * avkastPro / 100) + summaAr + (summaAr * avkastPro / 100); Console.WriteLine("Efter " + i + " år är totalen: " + konto); } } } }

Permalänk
Medlem

@beachroadsix: int summaAr = 12 * int.Parse(strPengar);

Sedan borde du inte ha det som en int. Men men...

Permalänk
Skrivet av ToddTheOdd:

@beachroadsix: int summaAr = 12 * int.Parse(strPengar);

Sedan borde du inte ha det som en int. Men men...

Jag vet, borde väl ha double. Men det kändes bara enklare att använda int hela vägen, hade nog med bekymmer ändå.
Tips på förkortningar av koden är alltid välkommet

Permalänk
Medlem
Skrivet av beachroadsix:

Tyckte jag hade provat alla möjliga varianter förut, men fick det inte att fungera. Så öppnade koden igen, och testade en sak, och vips, så fungerade det. Men var kanske inte den lösningen du hade tänkte dig? Tack

Jo, det var precis så jag (och många andra i tråden) tänke mig. Ursäkta att vi kan vara lite vaga i våra förslag, men du lär dig ju mer på att komma på lösningen själv

Skrivet av beachroadsix:

Tips på förkortningar av koden är alltid välkommet

Istället för var = var + ... så kan man skriva var += ... om man vill addera något till en variabel (samma gäller för övriga aritmetiska operatorer, d.v.s. -=, *=, o.s.v.).

Permalänk
Skrivet av perost:

Jo, det var precis så jag (och många andra i tråden) tänke mig. Ursäkta att vi kan vara lite vaga i våra förslag, men du lär dig ju mer på att komma på lösningen själv

Istället för var = var + ... så kan man skriva var += ... om man vill addera något till en variabel (samma gäller för övriga aritmetiska operatorer, d.v.s. -=, *=, o.s.v.).

Den var inte dum, ska försöka lära mig mer sånt. Enda jag lärt mig än är var++ (är väl samma som var = var + 1)

Permalänk
Medlem
Skrivet av beachroadsix:

Tyckte jag hade provat alla möjliga varianter förut, men fick det inte att fungera. Så öppnade koden igen, och testade en sak, och vips, så fungerade det. Men var kanske inte den lösningen du hade tänkte dig? Tack

using System; namespace Uträkning { class MainClass { public static void Main(string[] args) { int avkastPro = 0; int summaAr = 0; int year = 0; int konto = 0; Console.Write("Hur mycket vill du spara per månad: "); string strPengar = Console.ReadLine(); summaAr = int.Parse(strPengar); summaAr = summaAr * 12; Console.Write("Hur många år är ditt mål: "); string strYear = Console.ReadLine(); year = int.Parse(strYear); Console.Write("Vilken avkastning räknar du med: "); string strAvkastning = Console.ReadLine(); avkastPro = int.Parse(strAvkastning); Console.WriteLine((summaAr/12) + " per månad, i " + year + " år med " + avkastPro + "% avkastning"); for (int i = 1; i <= year; i++) { konto = konto + (konto * avkastPro / 100) + summaAr + (summaAr * avkastPro / 100); Console.WriteLine("Efter " + i + " år är totalen: " + konto); } } } }

Du skulle ju kunna förenkla uttrycket ganska mycket tex:
konto=(konto+summaAr)*(1+(avkastPro/100))

Och egentligen så behöver du inte någon loop alls då du kan lösa det på en rad med:

tot=(1+ränta)*summaAr*((((1+ränta)^year)-1)/ränta), där ränta=avkastPro/100

enl F(A):
https://en.wikipedia.org/wiki/Time_value_of_money

Men om du nu vill öva på koda så kan det vara bra att lägga till exceptions så att det tex inte går att mata in text i % variabeln, negativa årtal osv.

Visa signatur

Your COMMODORE 64 computer is equipped with one of the most sophisticated electronic music synthesizers available on any computer.
This chapter is an introduction to using your computer's sound chip, the SID chip.

Permalänk
Skrivet av ph33r:

Du skulle ju kunna förenkla uttrycket ganska mycket tex:
konto=(konto+summaAr)*(1+(avkastPro/100))

Och egentligen så behöver du inte någon loop alls då du kan lösa det på en rad med:

tot=(1+ränta)*summaAr*((((1+ränta)^year)-1)/ränta), där ränta=avkastPro/100

enl F(A):
https://en.wikipedia.org/wiki/Time_value_of_money

Men om du nu vill öva på koda så kan det vara bra att lägga till exceptions så att det tex inte går att mata in text i % variabeln, negativa årtal osv.

Tack för tipsen, ska testa lite mer.
Exceptions, är det samma som Try&Catch? Har bara läst lite om det, men ska ge det lite tid också.

Permalänk
Medlem
Skrivet av beachroadsix:

Tack för tipsen, ska testa lite mer.
Exceptions, är det samma som Try&Catch? Har bara läst lite om det, men ska ge det lite tid också.

I detta fall hade jag kört en TryParse bara, ger ett bool-värde som du enkelt kan kontrollera i en loop.

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av beachroadsix:

Tack för tipsen, ska testa lite mer.
Exceptions, är det samma som Try&Catch? Har bara läst lite om det, men ska ge det lite tid också.

TryCatch fångar upp exceptions och därifrån kan du ta hand om dem. Så nej, inte samma sak men går hand i hand.

Men som ovan skriver så är TryParse en bra metod i ditt fall.

Edit: Jag gissar på att personen du svarade på tidigare menade att skriva exception handling istället för bara exceptions och därav kanske du blev lite förvirrad. Eftersom exceptions är något som uppkommer vid fel i programmet. Och om det inte tas hand om så kraschar programmet.