Kassasystem, avrunda öre till hela och halva.

Permalänk

Kassasystem, avrunda öre till hela och halva.

Hej! Jag har en skoluppgift där jag ska beräkna växel baserat på pris och hur mycket användaren betalar som de får mata in. Mitt problem är när det kommer till hur jag ska avrunda ören. "Vi utgår från att 50 öre fortfarande används. Växeln avrundas till närmsta 50 öre. Om antalet öre är < 25 avrundas växeln neråt till 0, om det ligger mellan 25 och 75 avrundas växeln till 50 öre och om det är >75 avrundas växeln upp till en krona."

Har kollat över hela internet, de flesta forum men inte kommit fram till en lösning. Finns det någon här som hade kunnat ge mig en liten spark i röven på detta. Man ska få in allt detta i en loop också, jag har valt mig av en while loop, ska jag köra på en if loop istället? Övriga tips och förbättringar mottages gärna.

Kod nedan

using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Inlämningsuppgift_1__Växel { internal class Program { static void Main(string[] args) { // Meddelande som välkomnar användaren. Console.WriteLine("Hej och välkommen till kassan, jag ska nu hjälpa dig att beräkna din växel!"); // Deklarerar variablerna jag ska använda. Vissa har double då jag de ska kunna behandla decimaler. Int för de som är heltal double price; double paidAmount; double change; int thousandBills; int fiveHundredBills; int hundredBills; int fiftyBills; int twentyBills; int tenCrowns; int fiveCrowns; int oneCrown; double halfCrown; Console.Write("Mata in varans pris: "); // Ber användaren att mata in pris för varan. price = Convert.ToDouble(Console.ReadLine()); // Gör om användarens svar från string till double. Console.Write("Mata in ditt betalade belopp: "); // Ber användaren mata in betalat belopp. paidAmount = Convert.ToDouble(Console.ReadLine()); // Gör om användarens svar från string till double. change = paidAmount - price; // Tilldelar variablen "change" genom att subtrahera betalade beloppet från priset. Console.WriteLine("Din växel är: " + change + "kr"); // Skriver ut växeln användaren får med hjälp av variabeln "change". while (change > 0) // While loop som kör sålänge växeln är mer än 0. Dvs så länge det finns växel att räkna på så kör den { thousandBills = (int)change / 1000; change = change % 1000; Console.WriteLine("Antal 1000-sedlar: "+ thousandBills); // Skriver ut antal 1000-sedlar till konsolen. fiveHundredBills = (int)change / 500; change = change % 500; Console.WriteLine("Antal 500-sedlar: " + fiveHundredBills); // Skriver ut antal 500-sedlar till konsolen. hundredBills = (int)change / 100; change = change % 100; Console.WriteLine("Antal 100-sedlar: " + hundredBills); // Skriver ut antal 100-sedlar till konsolen. fiftyBills = (int)change / 50; change = change % 50; Console.WriteLine("Antal 50-sedlar: "+ fiftyBills); // Skriver ut antal 50-sedlar till konsolen. twentyBills = (int)change / 20; change = change % 20; Console.WriteLine("Antal 20-sedlar: " + twentyBills); // Skriver ut antal 20-sedlar till konsolen. tenCrowns = (int)change / 10; change = change % 10; Console.WriteLine("Antal 10-mynt: " + tenCrowns); // Skriver ut antal 10-kronor till konsolen. fiveCrowns = (int)change / 5; change = change % 5; Console.WriteLine("Antal 5-mynt: " + fiveCrowns); // Skriver ut antal 5-kronor till konsolen. oneCrown = (int)change / 1; change = change % 1; Console.WriteLine("Antal 1-mynt: " + oneCrown); // Skriver ut antal 1-kronor till konsolen. halfCrown = (double)change * 2; change = change % 0.5; Console.WriteLine("Antal 50-öre: " + halfCrown); // Skriver ut antal 50-ören till konsolen. } // Försökt att få in dessa på lämpliga ställen men inte kommit fram till ett lyckat resultat. // change = Math.Round(change * 4, MidpointRounding.ToEven) / 4; // change = Math.Round(change * 2.0d / 2.0d); Console.ReadLine(); } } }

Permalänk
Medlem

Det finns ingen mening med att ha enbart växelkoden i en loop, efter att du gjort uträkningen en gång så finns det ju inget kvar att växla. Om uppgiften säger att du ska använda en loop så menar de nog att du ska ha även inmatningen i loopen för att tillåta användaren räkna ut växel på flera belopp istället för att programmet bara avslutas direkt. Men börja i så fall med att få programmet att fungera korrekt för en inmatning, sen kan du fundera på hur du ska lägga in en loop.

Permalänk
Medlem

Om öre är mellan .00 och .24, sätt öre till .00
Om öre är mellan .25 och .74, sätt öre till .50
Om öre är mellan .75 och .99, lägg till 1.00 på heltalsbeloppet.

Visa signatur

Moderkort: Gigabyte X570 Aorus Master | CPU: AMD Ryzen R9 5900X | CPU-kylare: Noctua NH-D15 chromax.black | RAM: Corsair Vengeance LPX 64 GB (4x16) DDR4-3600 CL18 | GPU: Gigabyte RTX 4080 Eagle OC | SSD: 2 x Samsung 970 EVO Plus 1 TB NVMe + Kingston A400 480 GB + Samsung QVO860 1 TB | PSU: EVGA SuperNOVA G2 1000 W Gold | Chassi: Lian Li O11 Dynamic XL | Skärm: BenQ PD3200U @ 3840x2160 + ASUS ROG Strix XG32VQ @ 2560x1440 | Tangentbord: Corsair K68 RGB Cherry MX Red | Mus: Logitech MX Master 2S

Permalänk
Skrivet av cyklonen:

Om öre är mellan .00 och .24, sätt öre till .00
Om öre är mellan .25 och .74, sätt öre till .50
Om öre är mellan .75 och .99, lägg till 1.00 på heltalsbeloppet.

Är det då enklast att läsa in det som en string och använda sig utav SubString metoden eller finns det något enklare alternativ?

Permalänk
Medlem
Skrivet av Sandbranch:

Är det då enklast att läsa in det som en string och använda sig utav SubString metoden eller finns det något enklare alternativ?

Ingen aning. Jag kan inte koda.

Visa signatur

Moderkort: Gigabyte X570 Aorus Master | CPU: AMD Ryzen R9 5900X | CPU-kylare: Noctua NH-D15 chromax.black | RAM: Corsair Vengeance LPX 64 GB (4x16) DDR4-3600 CL18 | GPU: Gigabyte RTX 4080 Eagle OC | SSD: 2 x Samsung 970 EVO Plus 1 TB NVMe + Kingston A400 480 GB + Samsung QVO860 1 TB | PSU: EVGA SuperNOVA G2 1000 W Gold | Chassi: Lian Li O11 Dynamic XL | Skärm: BenQ PD3200U @ 3840x2160 + ASUS ROG Strix XG32VQ @ 2560x1440 | Tangentbord: Corsair K68 RGB Cherry MX Red | Mus: Logitech MX Master 2S

Permalänk
Medlem
Skrivet av cyklonen:

Ingen aning. Jag kan inte koda.

Lol's

Men det är precis så programering skrivs.. = )

Visa signatur

42? Seven and a half million years and all you can come up with is 42?!
► FD Define R2 | Win11Pro | R7-5800X | PA 120SE | ROG STRIX B550-F GAMING | CMN32GX4M2Z4600C18 | 1080 Ti | AX750 | Asus VG27WQ | HP Z27n |► Realme GT Master |

Permalänk
Medlem
Skrivet av xfade:

Lol's

Men det är precis så programering skrivs.. = )

Jag kan skriva logik, men inte faktisk kod. Det är så jävla många olika tecken och ord att hålla reda på. Sånt orkar jag inte med.

Visa signatur

Moderkort: Gigabyte X570 Aorus Master | CPU: AMD Ryzen R9 5900X | CPU-kylare: Noctua NH-D15 chromax.black | RAM: Corsair Vengeance LPX 64 GB (4x16) DDR4-3600 CL18 | GPU: Gigabyte RTX 4080 Eagle OC | SSD: 2 x Samsung 970 EVO Plus 1 TB NVMe + Kingston A400 480 GB + Samsung QVO860 1 TB | PSU: EVGA SuperNOVA G2 1000 W Gold | Chassi: Lian Li O11 Dynamic XL | Skärm: BenQ PD3200U @ 3840x2160 + ASUS ROG Strix XG32VQ @ 2560x1440 | Tangentbord: Corsair K68 RGB Cherry MX Red | Mus: Logitech MX Master 2S

Permalänk
Medlem

Dubbla talet
Använd math.floor eller liknande
Halvera talet

Permalänk
Medlem

En annan sak... Din kod verkar ämnad att minimera antalet sedlar/mynt. Man skulle kunna ändra fokus så den minimerar antalet olika valörer. T ex ge tre femhundringar i växel i stället för en tusenlapp och en femhundring. I alla fall om antalet av den högre valören är upp till två, t ex. Så 2500 i växel ger tre tusenlappar och en femhundring, men 2000 i växel ger fyra femhundringar. Mer realistiskt för hur kontanter används och hur en person i en kassa vill arbeta. Enklare att räkna upp några fler av samma sedel än att växla mellan alla möjliga sedelfack.

Visa signatur

Moderkort: Gigabyte X570 Aorus Master | CPU: AMD Ryzen R9 5900X | CPU-kylare: Noctua NH-D15 chromax.black | RAM: Corsair Vengeance LPX 64 GB (4x16) DDR4-3600 CL18 | GPU: Gigabyte RTX 4080 Eagle OC | SSD: 2 x Samsung 970 EVO Plus 1 TB NVMe + Kingston A400 480 GB + Samsung QVO860 1 TB | PSU: EVGA SuperNOVA G2 1000 W Gold | Chassi: Lian Li O11 Dynamic XL | Skärm: BenQ PD3200U @ 3840x2160 + ASUS ROG Strix XG32VQ @ 2560x1440 | Tangentbord: Corsair K68 RGB Cherry MX Red | Mus: Logitech MX Master 2S

Permalänk
Medlem

Jag har suttit en stund och försökt lösa detta. Jag har logiken, men det verkar fan stört omöjligt att få in variabeln "oneCrown" i en if-sats under den. Nån kodwizard kan det säkert, men jag klarar det inte. Därför kan jag inte heller använda mig av värdet i den variabeln i if-satsen, och då funkar inte min kod. Verkar vara nåt trams i C# att variabler är mycket mer låsta än i närbesläktade språk.

Det är på grund av såna här idiotiska begränsningar i språk som jag inte orkar med programmering. Det är för många konstiga "lösningar" som neckbeards hittat på.

Visa signatur

Moderkort: Gigabyte X570 Aorus Master | CPU: AMD Ryzen R9 5900X | CPU-kylare: Noctua NH-D15 chromax.black | RAM: Corsair Vengeance LPX 64 GB (4x16) DDR4-3600 CL18 | GPU: Gigabyte RTX 4080 Eagle OC | SSD: 2 x Samsung 970 EVO Plus 1 TB NVMe + Kingston A400 480 GB + Samsung QVO860 1 TB | PSU: EVGA SuperNOVA G2 1000 W Gold | Chassi: Lian Li O11 Dynamic XL | Skärm: BenQ PD3200U @ 3840x2160 + ASUS ROG Strix XG32VQ @ 2560x1440 | Tangentbord: Corsair K68 RGB Cherry MX Red | Mus: Logitech MX Master 2S

Permalänk
Medlem
Skrivet av Sandbranch:

Hej! Jag har en skoluppgift där jag ska beräkna växel baserat på pris och hur mycket användaren betalar som de får mata in. Mitt problem är när det kommer till hur jag ska avrunda ören. "Vi utgår från att 50 öre fortfarande används. Växeln avrundas till närmsta 50 öre. Om antalet öre är < 25 avrundas växeln neråt till 0, om det ligger mellan 25 och 75 avrundas växeln till 50 öre och om det är >75 avrundas växeln upp till en krona."

Har kollat över hela internet, de flesta forum men inte kommit fram till en lösning. Finns det någon här som hade kunnat ge mig en liten spark i röven på detta. Man ska få in allt detta i en loop också, jag har valt mig av en while loop, ska jag köra på en if loop istället? Övriga tips och förbättringar mottages gärna.

Kod nedan

using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Inlämningsuppgift_1__Växel { internal class Program { static void Main(string[] args) { // Meddelande som välkomnar användaren. Console.WriteLine("Hej och välkommen till kassan, jag ska nu hjälpa dig att beräkna din växel!"); // Deklarerar variablerna jag ska använda. Vissa har double då jag de ska kunna behandla decimaler. Int för de som är heltal double price; double paidAmount; double change; int thousandBills; int fiveHundredBills; int hundredBills; int fiftyBills; int twentyBills; int tenCrowns; int fiveCrowns; int oneCrown; double halfCrown; Console.Write("Mata in varans pris: "); // Ber användaren att mata in pris för varan. price = Convert.ToDouble(Console.ReadLine()); // Gör om användarens svar från string till double. Console.Write("Mata in ditt betalade belopp: "); // Ber användaren mata in betalat belopp. paidAmount = Convert.ToDouble(Console.ReadLine()); // Gör om användarens svar från string till double. change = paidAmount - price; // Tilldelar variablen "change" genom att subtrahera betalade beloppet från priset. Console.WriteLine("Din växel är: " + change + "kr"); // Skriver ut växeln användaren får med hjälp av variabeln "change". while (change > 0) // While loop som kör sålänge växeln är mer än 0. Dvs så länge det finns växel att räkna på så kör den { thousandBills = (int)change / 1000; change = change % 1000; Console.WriteLine("Antal 1000-sedlar: "+ thousandBills); // Skriver ut antal 1000-sedlar till konsolen. fiveHundredBills = (int)change / 500; change = change % 500; Console.WriteLine("Antal 500-sedlar: " + fiveHundredBills); // Skriver ut antal 500-sedlar till konsolen. hundredBills = (int)change / 100; change = change % 100; Console.WriteLine("Antal 100-sedlar: " + hundredBills); // Skriver ut antal 100-sedlar till konsolen. fiftyBills = (int)change / 50; change = change % 50; Console.WriteLine("Antal 50-sedlar: "+ fiftyBills); // Skriver ut antal 50-sedlar till konsolen. twentyBills = (int)change / 20; change = change % 20; Console.WriteLine("Antal 20-sedlar: " + twentyBills); // Skriver ut antal 20-sedlar till konsolen. tenCrowns = (int)change / 10; change = change % 10; Console.WriteLine("Antal 10-mynt: " + tenCrowns); // Skriver ut antal 10-kronor till konsolen. fiveCrowns = (int)change / 5; change = change % 5; Console.WriteLine("Antal 5-mynt: " + fiveCrowns); // Skriver ut antal 5-kronor till konsolen. oneCrown = (int)change / 1; change = change % 1; Console.WriteLine("Antal 1-mynt: " + oneCrown); // Skriver ut antal 1-kronor till konsolen. halfCrown = (double)change * 2; change = change % 0.5; Console.WriteLine("Antal 50-öre: " + halfCrown); // Skriver ut antal 50-ören till konsolen. } // Försökt att få in dessa på lämpliga ställen men inte kommit fram till ett lyckat resultat. // change = Math.Round(change * 4, MidpointRounding.ToEven) / 4; // change = Math.Round(change * 2.0d / 2.0d); Console.ReadLine(); } } }

Det ska väl inte vara:
change = Math.Round(change * 2.0d / 2.0d);

Det innanför parantesen är samma sak som change, gånger och delat räknas innan avrundningen, så det blir rundat till hela kronor

Det ska väl istället vara:
change = Math.Round(change * 2.0d) / 2.0d;
Om du först dubblerar, sen avtundar och sen halverar blir det rätt

Enklast i alla dessa fall är att göra tre rader av det, då kan det inte gå fel och är oftast tydligare:
Var doubleChange = 2*change;
DoubleChange = round(doubleChange);
Change = doubleChange/2d;

Permalänk
Medlem
Skrivet av medbor:

Det ska väl inte vara:
change = Math.Round(change * 2.0d / 2.0d);

Det innanför parantesen är samma sak som change, gånger och delat räknas innan avrundningen, så det blir rundat till hela kronor

Det ska väl istället vara:
change = Math.Round(change * 2.0d) / 2.0d;
Om du först dubblerar, sen avtundar och sen halverar blir det rätt

Enklast i alla dessa fall är att göra tre rader av det, då kan det inte gå fel och är oftast tydligare:
Var doubleChange = 2*change;
DoubleChange = round(doubleChange);
Change = doubleChange/2d;

Problemet med koden som den är, och även med detta tillägg, är att om örena avrundas upp till hel krona, så ska det läggas till en krona, men vid den punkten i koden har antalet enkronor redan skrivits ut.

Visa signatur

Moderkort: Gigabyte X570 Aorus Master | CPU: AMD Ryzen R9 5900X | CPU-kylare: Noctua NH-D15 chromax.black | RAM: Corsair Vengeance LPX 64 GB (4x16) DDR4-3600 CL18 | GPU: Gigabyte RTX 4080 Eagle OC | SSD: 2 x Samsung 970 EVO Plus 1 TB NVMe + Kingston A400 480 GB + Samsung QVO860 1 TB | PSU: EVGA SuperNOVA G2 1000 W Gold | Chassi: Lian Li O11 Dynamic XL | Skärm: BenQ PD3200U @ 3840x2160 + ASUS ROG Strix XG32VQ @ 2560x1440 | Tangentbord: Corsair K68 RGB Cherry MX Red | Mus: Logitech MX Master 2S

Permalänk
Medlem
Skrivet av cyklonen:

Problemet med koden som den är, och även med detta tillägg, är att om örena avrundas upp till hel krona, så ska det läggas till en krona, men vid den punkten i koden har antalet enkronor redan skrivits ut.

Njae… den raden ska ju in precis i början

Den där halvkronesavrundningen kan man ju göra i första steget innan man ens skriver ut change

Men nu insåg jag att det ju är priset som ska avrundas, inte växeln, men det borde gå ganska jämnt upp

Permalänk
Medlem

Efter lite mer funderande så inser jag att helkronesavrundningen vandrar uppåt, så den kollen måste göras först, och sen behöver resultatet läggas till för alla heltalsevalueringar därefter.

Visa signatur

Moderkort: Gigabyte X570 Aorus Master | CPU: AMD Ryzen R9 5900X | CPU-kylare: Noctua NH-D15 chromax.black | RAM: Corsair Vengeance LPX 64 GB (4x16) DDR4-3600 CL18 | GPU: Gigabyte RTX 4080 Eagle OC | SSD: 2 x Samsung 970 EVO Plus 1 TB NVMe + Kingston A400 480 GB + Samsung QVO860 1 TB | PSU: EVGA SuperNOVA G2 1000 W Gold | Chassi: Lian Li O11 Dynamic XL | Skärm: BenQ PD3200U @ 3840x2160 + ASUS ROG Strix XG32VQ @ 2560x1440 | Tangentbord: Corsair K68 RGB Cherry MX Red | Mus: Logitech MX Master 2S

Permalänk
Medlem
Skrivet av cyklonen:

Efter lite mer funderande så inser jag att helkronesavrundningen vandrar uppåt, så den kollen måste göras först, och sen behöver resultatet läggas till för alla heltalsevalueringar därefter.

Ja precis

99kr och 88 öre blir ju 100kr

Permalänk
Medlem

Ok, nu har jag nåt som jag tycker verkar funka som det är tänkt. Det finns garanterat smidigare och elegantare sätt att lösa det, men om det funkar så funkar det. Jag körde det i en online-tolk som inte verkar klara inmatning, så därför bytte jag ut inmatningsdelen med fasta värden som jag kunde snabbt kunde ändra för att se hur resultatet ändrades.

using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Inlämningsuppgift_1__Växel { internal class Program { static void Main(string[] args) { // Meddelande som välkomnar användaren. Console.WriteLine("Hej och välkommen till kassan, jag ska nu hjälpa dig att beräkna din växel! \n"); // Deklarerar variablerna jag ska använda. Vissa har double då jag de ska kunna behandla decimaler. Int för de som är heltal double price; double paidAmount; double change; int thousandBills; int fiveHundredBills; int hundredBills; int fiftyBills; int twentyBills; int tenCrowns; int fiveCrowns; int oneCrown; int halfCrown; price = 70.17; // Gör om användarens svar från string till double. Console.WriteLine("Varans pris: " + price + "\n"); // Ber användaren att mata in pris för varan. paidAmount = 419.92; // Gör om användarens svar från string till double. Console.WriteLine("Ditt betalade belopp: " + paidAmount + "\n"); // Ber användaren mata in betalat belopp. change = paidAmount - price; // Tilldelar variablen "change" genom att subtrahera betalade beloppet från priset. Console.WriteLine("Din växel är: " + change + "kr \n"); // Skriver ut växeln användaren får med hjälp av variabeln "change". while (change > 0) // While loop som kör sålänge växeln är mer än 0. Dvs så länge det finns växel att räkna på så kör den { double importvariabel = change - (Math.Floor(change)); //Plockar ut öresdelen av beloppet, utan heltal int exportvariabel = 0; //Initierar variabeln som lägger till antalet femtioöringar if (importvariabel > 0.745) //Kollar om öresdelen ska avrundas uppåt till hel krona { change = change + 1; //Adderar en krona till växelbeloppet } else if (importvariabel < 0.245) //Kollar om öresdelen ska avrundas ner till noll, och gör då inget { } else { exportvariabel = 1; //Lägger till en femtioöring om öresdelen avrundar till femtio öre }; halfCrown = exportvariabel; //För över antalet femtioöringar till den externa variabeln change = (Math.Floor(change)); //Gör om "change"-variabeln till heltal, eftersom öresdelen inte längre behövs thousandBills = (int)change / 1000; change = change % 1000; Console.WriteLine("Antal 1000-sedlar: "+ thousandBills); // Skriver ut antal 1000-sedlar till konsolen. fiveHundredBills = (int)change / 500; change = change % 500; Console.WriteLine("Antal 500-sedlar: " + fiveHundredBills); // Skriver ut antal 500-sedlar till konsolen. hundredBills = (int)change / 100; change = change % 100; Console.WriteLine("Antal 100-sedlar: " + hundredBills); // Skriver ut antal 100-sedlar till konsolen. fiftyBills = (int)change / 50; change = change % 50; Console.WriteLine("Antal 50-sedlar: "+ fiftyBills); // Skriver ut antal 50-sedlar till konsolen. twentyBills = (int)change / 20; change = change % 20; Console.WriteLine("Antal 20-sedlar: " + twentyBills); // Skriver ut antal 20-sedlar till konsolen. tenCrowns = (int)change / 10; change = change % 10; Console.WriteLine("Antal 10-mynt: " + tenCrowns); // Skriver ut antal 10-kronor till konsolen. fiveCrowns = (int)change / 5; change = change % 5; Console.WriteLine("Antal 5-mynt: " + fiveCrowns); // Skriver ut antal 5-kronor till konsolen. oneCrown = (int)change / 1; change = change % 1; Console.WriteLine("Antal 1-mynt: " + oneCrown); // Skriver ut antal 1-kronor till konsolen. Console.WriteLine("Antal 50-öre: " + halfCrown); // Skriver ut antal 50-ören till konsolen. change = 0; //Nollar "change" så att det inte loopar i all evighet } Console.ReadLine(); } } }

Visa signatur

Moderkort: Gigabyte X570 Aorus Master | CPU: AMD Ryzen R9 5900X | CPU-kylare: Noctua NH-D15 chromax.black | RAM: Corsair Vengeance LPX 64 GB (4x16) DDR4-3600 CL18 | GPU: Gigabyte RTX 4080 Eagle OC | SSD: 2 x Samsung 970 EVO Plus 1 TB NVMe + Kingston A400 480 GB + Samsung QVO860 1 TB | PSU: EVGA SuperNOVA G2 1000 W Gold | Chassi: Lian Li O11 Dynamic XL | Skärm: BenQ PD3200U @ 3840x2160 + ASUS ROG Strix XG32VQ @ 2560x1440 | Tangentbord: Corsair K68 RGB Cherry MX Red | Mus: Logitech MX Master 2S

Permalänk
Medlem
Skrivet av medbor:

Det ska väl inte vara:
change = Math.Round(change * 2.0d / 2.0d);

Det innanför parantesen är samma sak som change, gånger och delat räknas innan avrundningen, så det blir rundat till hela kronor

Det ska väl istället vara:
change = Math.Round(change * 2.0d) / 2.0d;
Om du först dubblerar, sen avtundar och sen halverar blir det rätt

Enklast i alla dessa fall är att göra tre rader av det, då kan det inte gå fel och är oftast tydligare:
Var doubleChange = 2*change;
DoubleChange = round(doubleChange);
Change = doubleChange/2d;

För mig är det A och O att kod ska vara så lättbegriplig som möjligt. Så även om det är matematiskt korrekt att dubblera, avrunda och sedan halvera, så är det inte helt intuitivt vad som sker. Dels så förutsätter det att den som läser koden vet de exakta förutsättningarna (att den lägsta valören är 50 öre), och att man därför kan dubblera och sedan avrunda. Men om lägsta valören istället vore 25 öre, så ska du alltså fyrdubbla innan du avrundar, etc. Så i min värld skulle en sådan lösning gå bort.

Det är betydlgt tydligare att ta fram öres-delen av talet och sedan avgöra hur det ska avrundas.

Skrivet av cyklonen:

Ok, nu har jag nåt som jag tycker verkar funka som det är tänkt. Det finns garanterat smidigare och elegantare sätt att lösa det, men om det funkar så funkar det. Jag körde det i en online-tolk som inte verkar klara inmatning, så därför bytte jag ut inmatningsdelen med fasta värden som jag kunde snabbt kunde ändra för att se hur resultatet ändrades.

using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Inlämningsuppgift_1__Växel { internal class Program { static void Main(string[] args) { // Meddelande som välkomnar användaren. Console.WriteLine("Hej och välkommen till kassan, jag ska nu hjälpa dig att beräkna din växel! \n"); // Deklarerar variablerna jag ska använda. Vissa har double då jag de ska kunna behandla decimaler. Int för de som är heltal double price; double paidAmount; double change; int thousandBills; int fiveHundredBills; int hundredBills; int fiftyBills; int twentyBills; int tenCrowns; int fiveCrowns; int oneCrown; int halfCrown; price = 70.17; // Gör om användarens svar från string till double. Console.WriteLine("Varans pris: " + price + "\n"); // Ber användaren att mata in pris för varan. paidAmount = 419.92; // Gör om användarens svar från string till double. Console.WriteLine("Ditt betalade belopp: " + paidAmount + "\n"); // Ber användaren mata in betalat belopp. change = paidAmount - price; // Tilldelar variablen "change" genom att subtrahera betalade beloppet från priset. Console.WriteLine("Din växel är: " + change + "kr \n"); // Skriver ut växeln användaren får med hjälp av variabeln "change". while (change > 0) // While loop som kör sålänge växeln är mer än 0. Dvs så länge det finns växel att räkna på så kör den { double importvariabel = change - (Math.Floor(change)); //Plockar ut öresdelen av beloppet, utan heltal int exportvariabel = 0; //Initierar variabeln som lägger till antalet femtioöringar if (importvariabel > 0.745) //Kollar om öresdelen ska avrundas uppåt till hel krona { change = change + 1; //Adderar en krona till växelbeloppet } else if (importvariabel < 0.245) //Kollar om öresdelen ska avrundas ner till noll, och gör då inget { } else { exportvariabel = 1; //Lägger till en femtioöring om öresdelen avrundar till femtio öre }; halfCrown = exportvariabel; //För över antalet femtioöringar till den externa variabeln change = (Math.Floor(change)); //Gör om "change"-variabeln till heltal, eftersom öresdelen inte längre behövs thousandBills = (int)change / 1000; change = change % 1000; Console.WriteLine("Antal 1000-sedlar: "+ thousandBills); // Skriver ut antal 1000-sedlar till konsolen. fiveHundredBills = (int)change / 500; change = change % 500; Console.WriteLine("Antal 500-sedlar: " + fiveHundredBills); // Skriver ut antal 500-sedlar till konsolen. hundredBills = (int)change / 100; change = change % 100; Console.WriteLine("Antal 100-sedlar: " + hundredBills); // Skriver ut antal 100-sedlar till konsolen. fiftyBills = (int)change / 50; change = change % 50; Console.WriteLine("Antal 50-sedlar: "+ fiftyBills); // Skriver ut antal 50-sedlar till konsolen. twentyBills = (int)change / 20; change = change % 20; Console.WriteLine("Antal 20-sedlar: " + twentyBills); // Skriver ut antal 20-sedlar till konsolen. tenCrowns = (int)change / 10; change = change % 10; Console.WriteLine("Antal 10-mynt: " + tenCrowns); // Skriver ut antal 10-kronor till konsolen. fiveCrowns = (int)change / 5; change = change % 5; Console.WriteLine("Antal 5-mynt: " + fiveCrowns); // Skriver ut antal 5-kronor till konsolen. oneCrown = (int)change / 1; change = change % 1; Console.WriteLine("Antal 1-mynt: " + oneCrown); // Skriver ut antal 1-kronor till konsolen. Console.WriteLine("Antal 50-öre: " + halfCrown); // Skriver ut antal 50-ören till konsolen. change = 0; //Nollar "change" så att det inte loopar i all evighet } Console.ReadLine(); } } }

Några pointers:

  • Indenteringen är inte korrekt, vilket gör det svårt att följa vart loopar och if-satser börjar och slutar.

  • Varför går du ned på 3 decimaler när du avgör avrundingen? Eftersom öre är en hundradel av en krona kommer du aldrig kunna ha ett tal som "0.245", utan det blir "0.24" eller "0.25".

  • Du har en tom else-if sats som alltså inte gör någonting, då är den också överflödig. Det är betydligt bättre att ändra så att else-if:en hanterar det du nu har i else, och sedan skippa else helt.

  • Din While-sats är totalt överflödig, då det är omöjligt för programmet att gå två varv i loopen då det sista du gör är att alltid nolla "change".

Permalänk
Medlem
Skrivet av Blomman90:

Några pointers:

  • Indenteringen är inte korrekt, vilket gör det svårt att följa vart loopar och if-satser börjar och slutar.

  • Varför går du ned på 3 decimaler när du avgör avrundingen? Eftersom öre är en hundradel av en krona kommer du aldrig kunna ha ett tal som "0.245", utan det blir "0.24" eller "0.25".

  • Du har en tom else-if sats som alltså inte gör någonting, då är den också överflödig. Det är betydligt bättre att ändra så att else-if:en hanterar det du nu har i else, och sedan skippa else helt.

  • Din While-sats är totalt överflödig, då det är omöjligt för programmet att gå två varv i loopen då det sista du gör är att alltid nolla "change".

1. Indenteringen ballade ur när jag klistrade in här. Orkade inte sitta och justera allt mitt i natten.
2. Därför att jag körde i en online-tolk (har inget program på datorn för att köra kod) och den hade kass precision på flyttal, så det blev 0.2400009 och sånt, så det var för att komma runt det.
3. Ja, jag har inte påstått att jag kan koda, så det blir vad det blir. Men det är tre separata fall som behöver hanteras, så det lär krävas tre "stickspår" i koden på nåt sätt.
4. While-satsen är inte min, utan fanns där från början, i trådstartarens kod. Jag adderade nollningen av "change" för att förhindra att loopen startade om.

Visa signatur

Moderkort: Gigabyte X570 Aorus Master | CPU: AMD Ryzen R9 5900X | CPU-kylare: Noctua NH-D15 chromax.black | RAM: Corsair Vengeance LPX 64 GB (4x16) DDR4-3600 CL18 | GPU: Gigabyte RTX 4080 Eagle OC | SSD: 2 x Samsung 970 EVO Plus 1 TB NVMe + Kingston A400 480 GB + Samsung QVO860 1 TB | PSU: EVGA SuperNOVA G2 1000 W Gold | Chassi: Lian Li O11 Dynamic XL | Skärm: BenQ PD3200U @ 3840x2160 + ASUS ROG Strix XG32VQ @ 2560x1440 | Tangentbord: Corsair K68 RGB Cherry MX Red | Mus: Logitech MX Master 2S

Permalänk
Medlem
Skrivet av Blomman90:

För mig är det A och O att kod ska vara så lättbegriplig som möjligt. Så även om det är matematiskt korrekt att dubblera, avrunda och sedan halvera, så är det inte helt intuitivt vad som sker. Dels så förutsätter det att den som läser koden vet de exakta förutsättningarna (att den lägsta valören är 50 öre), och att man därför kan dubblera och sedan avrunda. Men om lägsta valören istället vore 25 öre, så ska du alltså fyrdubbla innan du avrundar, etc. Så i min värld skulle en sådan lösning gå bort.

Det är betydlgt tydligare att ta fram öres-delen av talet och sedan avgöra hur det ska avrundas.

Några pointers:

  • Indenteringen är inte korrekt, vilket gör det svårt att följa vart loopar och if-satser börjar och slutar.

  • Varför går du ned på 3 decimaler när du avgör avrundingen? Eftersom öre är en hundradel av en krona kommer du aldrig kunna ha ett tal som "0.245", utan det blir "0.24" eller "0.25".

  • Du har en tom else-if sats som alltså inte gör någonting, då är den också överflödig. Det är betydligt bättre att ändra så att else-if:en hanterar det du nu har i else, och sedan skippa else helt.

  • Din While-sats är totalt överflödig, då det är omöjligt för programmet att gå två varv i loopen då det sista du gör är att alltid nolla "change".

Det man tekniskt sett gör är:
Växelsumman / minsta myntet
Avrunda detta till heltal
Multiplicera med minsta myntet

Alltså räkna om det från kronor till antal minsta mynt

Inte alls ologiskt eller konstigt enligt mig

Man byter alltså problem till ett som bättre passar uppgiften

Permalänk
Medlem

Jag är helkass på programmering och förstår inte ens vilket språk ovanstående är skrivet på, men lite javascript kan jag iaf knåpa ihop, och då blev det såhär. Möjligen är nåt av det översättningsbart till språket ovan.

var pris=21.25;
var betalt=100;
var retur=betalt-pris;
avrundat=Math.round(retur*2)/2;
alert("Varans pris = "+pris+"\nKunden ger = "+betalt+"\nVäxel tillbaka = "+avrundat);

sätt script runt det så kan det köras i webläsaren.

Permalänk
Medlem
Skrivet av Heliopause:

Jag är helkass på programmering och förstår inte ens vilket språk ovanstående är skrivet på, men lite javascript kan jag iaf knåpa ihop, och då blev det såhär. Möjligen är nåt av det översättningsbart till språket ovan.

var pris=21.25;
var betalt=100;
var retur=betalt-pris;
avrundat=Math.round(retur*2)/2;
alert("Varans pris = "+pris+"\nKunden ger = "+betalt+"\nVäxel tillbaka = "+avrundat);

sätt script runt det så kan det köras i webläsaren.

Det ser ut som om uppgiften är att räkna ut i vilka valörer växeln ska lämnas, inte enbart summan.

Visa signatur

Moderkort: Gigabyte X570 Aorus Master | CPU: AMD Ryzen R9 5900X | CPU-kylare: Noctua NH-D15 chromax.black | RAM: Corsair Vengeance LPX 64 GB (4x16) DDR4-3600 CL18 | GPU: Gigabyte RTX 4080 Eagle OC | SSD: 2 x Samsung 970 EVO Plus 1 TB NVMe + Kingston A400 480 GB + Samsung QVO860 1 TB | PSU: EVGA SuperNOVA G2 1000 W Gold | Chassi: Lian Li O11 Dynamic XL | Skärm: BenQ PD3200U @ 3840x2160 + ASUS ROG Strix XG32VQ @ 2560x1440 | Tangentbord: Corsair K68 RGB Cherry MX Red | Mus: Logitech MX Master 2S

Permalänk

Tack för all hjälp! Har lyckats lösa det nu och det verkar fungera fint!
La in detta: change = Math.Round(change * 2) / 2; innan den började rabbla upp hur många av varje den får upp

Console.Write("Mata in varans pris: "); // Ber användaren att mata in pris för varan. price = Convert.ToDouble(Console.ReadLine()); // Gör om användarens svar från string till double. Console.Write("Mata in ditt betalade belopp: "); // Ber användaren mata in betalat belopp. paidAmount = Convert.ToDouble(Console.ReadLine()); // Gör om användarens svar från string till double. change = paidAmount - price; // Tilldelar variablen "change" genom att subtrahera betalade beloppet från priset. change = Math.Round(change * 2) / 2; // Console.WriteLine("Din växel är: " + change + "kr"); // Skriver ut växeln användaren får med hjälp av variabeln "change"

.

Permalänk
Medlem
Skrivet av Sandbranch:

Tack för all hjälp! Har lyckats lösa det nu och det verkar fungera fint!
La in detta: change = Math.Round(change * 2) / 2; innan den började rabbla upp hur många av varje den får upp

Console.Write("Mata in varans pris: "); // Ber användaren att mata in pris för varan. price = Convert.ToDouble(Console.ReadLine()); // Gör om användarens svar från string till double. Console.Write("Mata in ditt betalade belopp: "); // Ber användaren mata in betalat belopp. paidAmount = Convert.ToDouble(Console.ReadLine()); // Gör om användarens svar från string till double. change = paidAmount - price; // Tilldelar variablen "change" genom att subtrahera betalade beloppet från priset. change = Math.Round(change * 2) / 2; // Console.WriteLine("Din växel är: " + change + "kr"); // Skriver ut växeln användaren får med hjälp av variabeln "change"

.

Kommentaren som saknas:
// avrundar antalet halvkronor till jämnt heltal och sedan tillbaka till kronor

Kan också skrivas som:
change = Math.Round(change / smallestCoin) * smallestCoin;

Där smallestCoin är minsta valören av mynt, i det här fallet 0.5kr

Permalänk
Medlem
Skrivet av medbor:

Kommentaren som saknas:
// avrundar antalet halvkronor till jämnt heltal och sedan tillbaka till kronor

Kan också skrivas som:
change = Math.Round(change / smallestCoin) * smallestCoin;

Där smallestCoin är minsta valören av mynt, i det här fallet 0.5kr

Notera att Math.Round i .NET som default använder "Round To Even" vid decimaltal som befinner sig mitt emellan två heltal, d.v.s. 0.5 => 0, 1.5 => 2, 2.5 => 2, 3.5 = 4 etc.

Om du har change = 0.25 och smallestCoin = 0.5 så räknar du sannolikt med att få tillbaks en femtioöring enligt:
Math.Round(0.25 / 0.5) * 0.5
Math.Round(0.5) * 0.5
1 * 0.5
0.5

Istället kommer du få:
Math.Round(0.25 / 0.5) * 0.5
Math.Round(0.5) * 0.5
0 * 0.5
0

För att få den förväntade avrundningen krävs att detta anges enligt följande:
Math.Round(0.25 / 0.5, MidpointRounding.AwayFromZero) * 0.5

Permalänk
Medlem
Skrivet av PeCe:

Notera att Math.Round i .NET som default använder "Round To Even" vid decimaltal som befinner sig mitt emellan två heltal, d.v.s. 0.5 => 0, 1.5 => 2, 2.5 => 2, 3.5 = 4 etc.

Om du har change = 0.25 och smallestCoin = 0.5 så räknar du sannolikt med att få tillbaks en femtioöring enligt:
Math.Round(0.25 / 0.5) * 0.5
Math.Round(0.5) * 0.5
1 * 0.5
0.5

Istället kommer du få:
Math.Round(0.25 / 0.5) * 0.5
Math.Round(0.5) * 0.5
0 * 0.5
0

För att få den förväntade avrundningen krävs att detta anges enligt följande:
Math.Round(0.25 / 0.5, MidpointRounding.AwayFromZero) * 0.5

Oj, det kändes som en dum grej. Inte kodat dotnet på länge märker jag