Avatar billede carbonic Nybegynder
29. november 2007 - 22:41 Der er 6 kommentarer og
3 løsninger

Basis løkke-problem, tjekke om int værdi er under 0

I mit program har jeg følgene problem, i programmet er der en calculate metode der kan blive givet en integer værdi med (kaldet a), den første ting den gør er at tjekke om a er under 0 med (a < 0)
{....}

Dette virker dog ikke og den går, videre i løkken. Hvorfor er så det store spørgsmål?

Her er koden hvis der er nogen der kan bruge det:
(gid eksperten var bedre til kode)

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;

/**
* CubeRootInvariant.java
* @author carbonic
* A gui with an inputfield, a output field and a calculate button
* Takes a number in the inputfield and gives the square root
* in the output field when you press the button.
*/
public class CubeRootInvariant {
    private static String result;
    static JTextField inputField = new JTextField(20);
    static JTextField outputField = new JTextField(20);

    /**
    * @param args
    * takes no arguments
    */
    public static void main(String[] args) {
       
            JFrame frame = new JFrame();
           
            final int FIELD_WIDTH = 20;
            final JTextField inputField = new JTextField(FIELD_WIDTH);
            final JTextField outputField = new JTextField(FIELD_WIDTH);
            outputField.setText("Result");
            inputField.setText("");
           
            JButton calculateButton = new JButton("Calculate square root");
            calculateButton.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent event) {
                    try {
                        calculate(Integer.parseInt(inputField.getText()));
                    }
                    catch (NumberFormatException e) {
                        result = "Int values only";
                    }
                    outputField.setText(result);
                }
            });
                   
            frame.setLayout(new FlowLayout());
            frame.add(calculateButton);
            frame.add(inputField);
            frame.add(outputField);   
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
    }

    /*/
    * Method that takes an integer value and sets the "result"
    * private variable to the square root of that number
    */
    public static void calculate(int a) {
        // Way better method:
        // wax =(int) Math.pow(a, 0.1e1 / 0.3e1);
       
        //*************Don't work********************
        if (a < 0) {
            result = "Negative values = Big nono";
        }
        //*******************************************
        if (((a < 1) && ( a > -1))) {
            result = "0";
        }
        else {
            int temp;
            temp = 1;
            // r^3 <=  a < (r+1)^3
            while (!((temp * temp * temp <= a) && (a < ((temp + 1) * (temp + 1) * (temp + 1))))) {
                temp++;
            }
            result = Integer.toString(temp);
        }
    }
}
Avatar billede nielle Nybegynder
29. november 2007 - 23:04 #1
Ret til:

        if (a < 0) {
            result = "Negative values = Big nono";
            return;   
        }

Hvis du ikke har en return så går programlogikken bare videre og så blivere "result" overskrevet med det der kommer via else-delen.
Avatar billede nielle Nybegynder
29. november 2007 - 23:06 #2
Du bør dog overveje at ændre calculate() til at returenere en string (værdien du nu gemmer i "result") i stedet for void. Det giver en bedre programlogik.
Avatar billede jakoba Nybegynder
29. november 2007 - 23:44 #3
variablen a er en int værdi. dvs den kan kun indeholde heltal.
så ((a < 1) && ( a > -1)) er det samme som
  ( a == 0 )
så reelt har du 3 separate situationer hvor kun en er korrekt når programmet kommer dertil

    if ( a < 0 ) {      // a er mindre end 0
        result = "Negative values = Big nono";
    } else {
        if ( a == 0 ) {    // a er 0
            result = "0";
        } else {        // så må a være større end 0
            int temp;
            temp = 1;
            // r^3 <=  a < (r+1)^3
            while (!((temp * temp * temp <= a) && (a < ((temp + 1) * (temp + 1) * (temp + 1))))) {
                temp++;
            }
            result = Integer.toString(temp);
        } // afslutter indre if-sætning
    } // afslutter ydre if-sætning

mvh JakobA
Avatar billede arne_v Ekspert
30. november 2007 - 02:31 #4
Jeg har flere forskellige forslag:

1)  Jeg mener at metode bør returnere en int eller smide en exception.

2)  Kubik rødder af negative tal er mulige, så ingen grund til at teste for negativ.
    Kvadrat rødder af negative tal er ikke mulige (indenfor reelle tal).

3)  temp++ må kunne optimeres.
Avatar billede arne_v Ekspert
30. november 2007 - 02:59 #5
Eller måske alligevel ikke.

To code snippets:

    public static int cubeRoot1(int v) {
        if(v < 0) {
            return -cubeRoot1(-v);
        } else {
            int res = 0;
            while(res*res*res < v) res++;
            return res;
        }
    }
    public static int cubeRoot2(int v) {
        if(v < 0) {
            return -cubeRoot2(-v);
        } else {
            double xres = 1;
            double tmp;
            do {
                tmp = xres;
                xres = tmp - (tmp*tmp*tmp - v)/(3*tmp*tmp);
            } while(xres - tmp > 0.1 || xres - tmp < -0.1);
            int res = (int)xres;
            if(res*res*res < v) res++;
            return res;
        }
    }
Avatar billede carbonic Nybegynder
30. november 2007 - 12:20 #6
Mange tak for de gode svar, skriv endelig et svar herinde alle 3 og i får alle point.

Dog flest til:
-nielle som svarede direkte på problemet

Lidt mindre til:
-jakoba som mere indirekte viste problemet med løkken ved at lave en ny, og påpegede at jeg kunne bruge ==, hvilket jeg dog generelt prøver at undgå da denne måde kun sammenligner referencer (hvilket dog vil virke her) og ikke værdier, og dette venter jeg med at være glad for at bruge til jeg bliver lidt mere sikker i hvad jeg laver.

Og en smule til:
-arne v
Avatar billede jakoba Nybegynder
30. november 2007 - 18:52 #7
OK.

Lige en kommentar til "da denne måde kun sammenligner referencer". Der har du misforstået noget. Det er lidt mere indviklet end som det.

Det handler om objekter versus værdier.

en variabel af typen int er en værdi og når du sammenligner 2 int vil det ALTID være værdierne der sammenlignes hvadenten du bruger >, <, ==, !=, >= eller <=. ALTID

en variabel af typen Integer er et objekt. dvs en beholder (objektet) der indeholder en værdi (af typen int). så hvis du har
Integer a, b;
og sammenligner med  ( a == b )  så er det beholderne (referencen) der sammenlignes. Det gælder også hvis du anvender en af de andre sammenlignings operatorer (>, <, !=, >= eller <=) så hvis du vil sammenligne værdier indeholdt i et objekt må du specifikt fortælle at det er værdien du snakker om og ikke beholderen
eg:  ( a.valueOf() == b.valueOf() )

Der misforståelsen ofte kommer fra er strenge som Java jo per definitioner altid gemmer som objekter med en værdier indeni, og som nybegynderen så prøver at sammenligne somom de var værdier
String a = "abc", b = "abc";
    if ( a == b )                      //duer ikke fordi den sammenligner beholderne
    if ( a.equals( b ) )                //sammenligner indholdet, så den duer

mvh JakobA
Avatar billede nielle Nybegynder
30. november 2007 - 19:13 #8
Svar :^)
Avatar billede arne_v Ekspert
01. december 2007 - 02:20 #9
.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester