Avatar billede imperten Nybegynder
29. april 2005 - 21:48 Der er 18 kommentarer

Underlig division

System.out.println(aktuel);
  felt[x][y] = aktuel / 4;

Der er noget jeg ikke helt forstår. Værdien af variablen aktuel kan være fra 0 til 11. I felt[][] skal optages en værdi mellem 0 og 2. Derfor division med 4. Både aktuel og felt[][] er oprettet som int variabler.

Det virker helt som det skal, fordi jeg indsætter System linjen ovenover. Hvis jeg fjerner den går det galt, så får felt[][] en værdi på 383713599. Underligt stort tal.

Hvis jeg undlader / 4 skriver den godt nok værdier mellem 0 og 11 ind i felt[][], også uden System linjen.

Er det ikke underligt?

Jeg har prøvet med parenteser omkring aktuel, hele udtrykket, og sågar (int)(aktuel) / 4. Men lige meget hjælper det.

System linjen ønsker jeg under alle omstændigheder ikke at bevare, da den forsænker programmet temmelig en del.
Avatar billede erikjacobsen Ekspert
29. april 2005 - 21:53 #1
Du må have noget kode udenom, ikke?
Avatar billede jakoba Nybegynder
29. april 2005 - 22:19 #2
har du husket { og } onkring den kode dine for løkker skal kontrollere?
bliver aktuel intialisered før løkkerne ?
Avatar billede imperten Nybegynder
29. april 2005 - 22:32 #3
for (int x = 0; x < 10; x++) {
            for (int y = 0; y < 10; y++) {
              if (aktivBrik[x][y] == 1) {
                if (aktuel < 4) {
                  felt[x][y] = 0;
                } else if (aktuel < 8) {
                  felt[x][y] = 1;
                } else {
                  felt[x][y] = 2;
                }
                aktivBrik[x][y] = 0;
              }
            }
          }

Nu har jeg løst problemet således. Og det virker!

Det der undrer mig er. Hvor pokker kommer det kæmpe store tal 383713599 fra, når man dividerer tal mellem 0 og 11 med 4 ??

aktuel og felt[][] er globale variabler defineret helt oppe i indledningen. Det burde være uden betydning.
Avatar billede erikjacobsen Ekspert
29. april 2005 - 22:44 #4
Det store tal kommer heller ikke fra divisionen, men af anden grund. Derfor vil jeg se mere kode, hvis problemet skal opklares.
Avatar billede imperten Nybegynder
29. april 2005 - 22:52 #5
Hele programmet fylder efterhånden 3.100 linjer. Det er lidt for omfattende at bringe her. Men her er hele underrutinen. Jeg tvivler på, det hjælper dig noget:

  void træk() {
    if (px < 480 && py < 70) {
      fx = px / 40;
      if (taget[fx] == 0) {
        ax = 4; ay = 2;
        brikAktiv = 1;
        rotation = 0;
        aktuel = fx;
      }
    } else if (px >= 414 && px < 476 && py >= 84 && py < 476) {
      int knapNr = (py - 84) / 66;
      if (knapNr == 0) {
        if (ok == 5) {
          taget[aktuel] = 1;
          brikAktiv = 0;
          for (int x = 0; x < 10; x++) {
            for (int y = 0; y < 10; y++) {
              if (aktivBrik[x][y] == 1) {
                if (aktuel < 4) {
                  felt[x][y] = 0;
                } else if (aktuel < 8) {
                  felt[x][y] = 1;
                } else {
                  felt[x][y] = 2;
                }
                aktivBrik[x][y] = 0;
              }
            }
          }
        }
      } else if (knapNr == 1) {
        if (rotation < 4) {
          rotation += 5;
          if (rotation == 8) rotation = 4;
          ax--; ay++;
        } else {
          rotation -= 3;
          if (rotation == 4) rotation = 0;
          ax++; ay--;
        }
      } else if (knapNr == 2) {
        if (rotation < 4) {
          rotation += 3;
          if (rotation == 3) rotation = 7;
          ax--; ay++;
        } else {
          rotation -= 5;
          if (rotation == -1) rotation = 3;
          ax++; ay--;
        }
      } else if (knapNr == 3) {
        if (rotation % 2 == 0) {
          rotation++;
        } else {
          rotation--;
        }
      } else if (knapNr == 4) {
        if (rotation < 4) {
          rotation = 3 - rotation;
        } else {
          rotation = 11 - rotation;
        }
      } else if (knapNr == 5) {
        for (int i = 0; i < 12; i++) {
          taget[i] = 0;
        }
        for (int x = 0; x < 10; x++) {
          for (int y = 0; y < 10; y++) {
            felt[x][y] = -1;
          }
        }
        brikAktiv = 0;
      }
    } else if (px < 400 && py >= 80 && py < 480) {
      fx = px / 40;
      fy = (py - 80) / 40;
      if (rotation < 4) {
        ax = fx - 1; ay = fy - 2;
      } else {
        ax = fx - 2; ay = fy - 1;
      }
    }
  }
Avatar billede erikjacobsen Ekspert
29. april 2005 - 23:22 #6
Nej, ud af det du viser her, kan man ikke se det. Et uinitialiseret array kan vel gøre det.

3000 linier er lidt meget. Og der står uforklarlige tal i det vi kan se. Det er vist ikke noget du kan have synderligt overblik over... ;)
Avatar billede imperten Nybegynder
29. april 2005 - 23:41 #7
Overblik ... jo såmænd. Det er testet bid for bid.

Et uinitialiseret array!? - nej det lader sig vist ikke gøre, uden at der kommer en fejl ved compilingen.
Avatar billede jakoba Nybegynder
30. april 2005 - 02:16 #8
et int array bliver automatisk mulstillet ved oprettelsen. Det er ønskværdigt at initialisere, men ikke strengt nødvendigt. alle celler starter med værdien 0 (eller null hvis det er et array af objekter).

>> imperten
  'testet bid for bid' er nogenlunde det samme som at sige 'jeg har intet overblik over denne kode', så i er helt enige.
  Faren ved 'bid for bid' er bi-effekter der pludselig dukker op et helt andet sted end i den kode man med succes har testet for noget andet. Og det ser ret meget ud til at være det der skete her.
Avatar billede jakoba Nybegynder
30. april 2005 - 02:30 #9
prøv engang med:

              if (aktivBrik[x][y] == 1) {
                // if (aktuel < 4) {
                //  felt[x][y] = 0;
                // } else if (aktuel < 8) {
                //  felt[x][y] = 1;
                // } else {
                //  felt[x][y] = 2;
                // }
                aktivBrik[x][y] = 0;
                felt[x][y] = aktuel / 4;
                if ( felt[x][y] > 3 ) {
                  System.out.println( "aktuel = " +aktuel
                                        +" (x,y)=(" +x +"," +y +")"
                                        +" felt[x][y] = " +felt[x][y]
                                      );
                }
              }
Avatar billede jakoba Nybegynder
30. april 2005 - 02:40 #10
i din allerførste if tester du IKKE om px og py er >= 0.
Det tror jeg du bør gøre. Også selvom du er 100% på at de aldrig er negative :)
Avatar billede _carsten Nybegynder
30. april 2005 - 13:11 #11
Hvis det virker når du indsætter System.out.println(aktuel);
tyder det jo på at du mangler {} et eller andet sted.

Jeg vil klart tilslutte mig erikjacobsen og jakoba, 3000 linier lyder som noget der skulle splittes op i 5-10 klasser med 8-10 metoder, så det er nemt at finde eventuelle fejl og skabe overskuelighed.

Hvis du poster 50 linier på hver side af det sted hvor du indsætter System.out.println(aktuel); er der måske en chance for at nogen kan finde løsningen
Avatar billede mollevp Nybegynder
30. april 2005 - 13:46 #12
"Hvis det virker når du indsætter System.out.println(aktuel);
tyder det jo på at du mangler {} et eller andet sted."

Hvordan det? Grunden til jeg spørger er at jeg selv har haft noget kode jeg ikke kunne finde fejlen i, men som kun virkede når jeg havde en System.out.println(); et bestemt sted..

Mvh morten
Avatar billede jakoba Nybegynder
30. april 2005 - 13:57 #13
if (condition der aldrig bliver sand)
    gør( noget );                    // metoden bliver ikke kaldt

if (condition der aldrig bliver sand)
    System.out.println( "?" );        // bliver ikke udført pga betingelsen
    gør( noget );                    // metoden bliver kaldt

det er en meget almindelig fejl.

men at dømme efter den kode vi kan se er imperten rigtig god til at indsætte { og } hver gang.
Avatar billede _carsten Nybegynder
30. april 2005 - 14:02 #14
Eks. 1
if(true)
  // gør noget
else
  // gør noget andet
  // gør noget tredje


Eks2.
if(true){
  // gør noget
}
else{
  // gør noget andet
  // gør noget tredje
}

I eks1. "gør noget tredje" udføres ALTID

i eks2. "gør noget tredje" udføres KUN hvis "gør noget andet" udføres
Avatar billede _carsten Nybegynder
30. april 2005 - 14:02 #15
Nå - for sent kan jeg se :)
Avatar billede _carsten Nybegynder
30. april 2005 - 14:16 #16
Det er rigigt at imperten er god til at sætte dem, men alligevel ikke konsekvent, da han kun anvender {} omkring if/else ikke ren if, og hvis resten af koden ser ud som det der er postet her, hvor der minimum er en { eller } på hver anden linie, så skal sættes ca. 1500 stk's 100% korrekt, så derfor - del koden op i nogle få klasser og metoder med max. 30 - 50 linier i hver, ellers kan der nemt smutte en { eller } et eller andet sted og den er bare umulig at finde.
Avatar billede imperten Nybegynder
30. april 2005 - 16:14 #17
Det er svært at overskue et program på forhånd, især når det fylder så meget. Det kan ikke undgås at man undervejs kommer til den erkendelse, at man skulle have gjort sådan og sådan i stedet. Men det med {} er ikke noget problem, når blot man konsekvent laver indryk hver gang. Hvor om alting er, programmet fungerer som det skal, med den lille omskrivning.

Inden felt[x][y] = aktuel / 4; er alle felt[12][12] sat til -1, indikering af et tomt felt. Men alt sammen forklarer det ikke, hvorfor eksempelvis 7 / 4 giver 383.713.599. Min egen forestilling var, at Java huskede en eller anden carry, men i såfald burde det have været cirka en fjerdedel af int's maxværdi. Men det er det heller ikke. Omsat til bits er det lig med: 1.0110.1101.1111.0000.0001.0011.1111.

Kryptisk tal - men det når konsekvent frem til det hver gang!? ... det er mig ubegribeligt.

Som I ser, dividerer jeg med 66 højere oppe, og der går intet galt. Når jeg trykker på de 6 knapper, opfører de sig, som de skal hver gang.

px og py er applettens pixelpunkter. De kan ikke blive negative.
Avatar billede arne_v Ekspert
30. april 2005 - 16:41 #18
Medmindre du kan poste et komplet program som kan genskabe fejlen, så kan
vi kun gætte.
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