Archief - JAVA: 6 + 2 + 5 = 15?

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

cosmo2

Legacy Member
Hey, ik ben een calculator aan het programmeren die alles wat je op 1 lijn ingeeft berekend. Ik heb alles gemaakt, maar zit nu met een probleempje waar hij inplaats van 6 + 2 + 5 doet, doet hij 6 + 2 + 2 + 5. Hij neemt het vorige getal en telt het bij(afhankelijk van de operator) het volgende getal, stockeert deze in een double, berekend de volgende 2 getallen en telt die bij de gestockeerde double op. Maar dat wil ik natuurlijk niet en ik denk toch dat 6 + 2 + 5 nog altijd 13 is.

Dit is mijn code waar hij berekend.
Code:
public double optellen(double x, double y){
        return x + y;
    }
    public double vermenigvuldigen(double x, double y){
        return x * y;
    }
    public double aftrekken(double x, double y){
        return x - y;
    }
    public double delen(double x, double y){
        return x / y;
    }
    public double procent(double x, double y){
        return x % y;
    }

public void berekenIngave(){
      for (int i = 0 ; i < args.length; i++){
            switch (args[i]) {
                case "+":
                    uitkomst = uitkomst + optellen(toDbl[i - 1], toDbl[i + 1]);
                    break;
                case "-":
                    uitkomst = uitkomst - aftrekken(toDbl[i - 1], toDbl[i + 1]);
                    break;
                case "/":
                    uitkomst = uitkomst / delen(toDbl[i - 1], toDbl[i + 1]);
                    break;
                case "%":
                    uitkomst = uitkomst % procent(toDbl[i - 1], toDbl[i + 1]);
                    break;
                case "*":
                    uitkomst = uitkomst * vermenigvuldigen(toDbl[i - 1], toDbl[i + 1]);
                    break;
            }
        }
      printUitkomst();
        
    }

Bij het debuggen zie ik dat hij inderdaad 6 + 2 = 8 doet en dan 8 + 2 + 5 = 15. Ik weet ook de reden waarom hij dit doet (uitkomst = uitkomst + ....), maar weet er geen oplossing voor.

Als ik 'uitkomst + ....' weglaat berekend hij alleen de laatste 2 getallen. (6 + 2 + 5 = 7)

Alvast bedankt!

nevek

Legacy Member
omdat je in de for met optellen(toDbl[i - 1], toDbl[i + 1]) werkt ga je met 2 getallen wel de juiste berekening hebben maar als je er een derde getal bij doet gaat het tweede getal nog een keer gebruiken

Vin

Legacy Member
Om te beginnen vind ik het een ietwat rare constructie, maar hetvolgende zou moeten werken:
- case getal: uitkomst = getal
- case binaire operator: uitkomst = operator(uitkomst, volgende argument); ++i;

die ++i zal er voor zorgen dat je onmiddellijk naar de volgende operator springt.
Er bestaan wel veel betere manieren om dit probleem aan te pakken (vb: je uitdrukking parsen in een boomstructuur), op deze manier verwaarloos je compleet de volgorde der operatoren.

cosmo2

Legacy Member
omdat je in de for met optellen(toDbl[i - 1], toDbl[i + 1]) werkt ga je met 2 getallen wel de juiste berekening hebben maar als je er een derde getal bij doet gaat het tweede getal nog een keer gebruiken

Ja, dat weet ik ;) Maar ik weet er geen oplossing voor.

@b0red:

Wat bedoel je juist met
- case getal: uitkomst = getal
?

EDIT: Hij springt inderdaad naar de volgende operator, maar hij berekend nog steeds fout.

En volgens de opgave moet er geen volgorde inzitten.

Vin

Legacy Member
Die case getal staat er zodat het eerste argument wordt ingelezen in de variabele, waarop je verder je operaties toepast.

Een andere mogelijkheid:
Code:
uitkomst = args[0];

for (int i = 1; i < args.length; ++i)
{
    switch (args[i]) 
    {
    case "operator1":
        uitkomst = operator1(uitkomst, args[i + 1]);
        break;
    case "operator2":
        uitkomst = operator2(uitkomst, args[i + 1]);
        break;
    }
}

of als je er van uit gaat dat een uitdrukking altijd van de vorm
getal operator getal operator getal operator getal ...
is, kan je de uitdrukking in de for lus schrijven als
for (int i = 1; i < args.length; i += 2)

cosmo2

Legacy Member
Bedankt b0red! Hij werkt nu inderdaad!
Nu we toch bezig zijn, heb ik nog een vraagje :D
Ik probeer een memory functie in te bouwen. Om je memory te setten moet je 'setm 1' (of 2/3) typen. Hij slaat dit op in 'String memOps' en via een if-structuur controleer ik dan welke char er op de 5e plaats staat. (s=0, e=1, t=2, m=3, *spatie*=4, *getal*=5), afhankelijk van dat char verwijs ik naar een andere methode die de invoer vraagt en opslaat in een Double (mem1/2/3). Maar zodra ik terug naar het begin van het programma (public void startIngave) ga, reset hij de Doubles naar 0. Dus ben ik mijn memory functie kwijt. Let niet op "rekencalc" en "uitkomst".

Ik post even de code:
Code:
public class Rekenmachine {
    double mem1, mem2, mem3;
    String memOps = " ";

   public void startIngave(){ //van zodra hij hier weer komt worden mem1,2 en 3 weer op 0 gezet
        String calc = "";

        while (!"STOP".equals(calc)){
            System.out.println("calc> ");
            calc = Input.readLine();
            calc = calc.toLowerCase();
            rekencalc = calc;
            
            if (calc.contains("stop")){
                 System.exit(0);
            }
            if (calc.equals("setm 1") | calc.equals("setm 2") | calc.equals("setm 3")){
                memOps = calc;
                opslaanGeheugen(); // ga naar methode opslaanGeheugen.
            }
            else if (calc.equals("display m1") | calc.equals("display m2") | calc.equals("display m3")){
                memOps = calc;
                opslaanGeheugen();
            }
        }
   }
public void mem1(){
        Rekenmachine rekmach = new Rekenmachine(); 
        System.out.println("m1: ");
        rekmach.mem1 = Input.readDouble();
        startIngave(); //Hier gaat hij terug naar het begin
    }
    
    public void mem2(){
        Rekenmachine rekmach = new Rekenmachine(); 
        System.out.println("m2: ");
        rekmach.mem2 = Input.readDouble();
        startIngave();
    }
    
    public void mem3(){
        Rekenmachine rekmach = new Rekenmachine(); 
        System.out.println("m3: ");
        rekmach.mem3 = Input.readDouble();
        startIngave();
    }
    
    public void opslaanGeheugen(){
        Rekenmachine rekmach = new Rekenmachine(); 
        if (memOps.charAt(5) == '1'){
            mem1(); // ga naar mem1 methode
        }
        else if (memOps.charAt(5) == '2'){
            mem2();
        }
        else if (memOps.charAt(5) == '3'){
            mem3();
        }
        else if (memOps.charAt(9) == '1'){
            System.out.println(rekmach.mem1);
        }
        else if (memOps.charAt(9) == '2'){
            System.out.println(rekmach.mem2);
        }
        else if (memOps.charAt(9) == '3'){
            System.out.println(rekmach.mem3);
        }
    }
}

Ik weet dat de code nog omslachtig is en "vuil", maar deze wordt nog opgekuist.

Vin

Legacy Member
Waarom maak je een nieuw rekenmachine object aan bij het aanroepen van die memfuncties? Zo ook dat object dat je aanmaakt bij opslaanGeheugen?

Aangezien mem1, mem2 en mem3 geen statische leden zijn, zijn zij voor elk object verschillend. Je moet dit zien als: elke keer je een "new Rekenmachine()" aanmaakt, is dit effectief een ander, nieuw rekentoestel, met zijn eigen geheugen (dataleden etc).

Wat je wil is: opslaan in het geheugen van DIT rekentoestel (this.memx, of gewoon memx).

Code:
if (memOps.charAt(5) == '1')
{
    mem1 = Input.readDouble();
} 
else if (memOps.charAt(9) == '1')
{
    System.out.println(mem1);
}

cosmo2

Legacy Member
Ja, dat dacht ik inderdaad al want hij maakte 2 objecten aan tijdens de debug. Alles is nu opgelost! Bedankt voor de hulp!
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan