Toon posts:

[JAVA] Maximale waarde long

Pagina: 1
Acties:
  • 192 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik wil in een java programma en loop laten lopen tot de maximale waarde van een long, het volgende heb ik geprobeerd:
code:
1
2
3
4
5
    while (val<9223372036854775802L)
        {   val*=8;
        
            System.out.println("val=" + val);
    }

Als ik de code uitvoer dan blijft het programma in een oneindige loop hangen en wordt er voor val de waarde 0 op het scherm afgedrukt. Je zou verwachten dat al val de maximale waarde van een long bereikt uit de loop zou springen. Hoe kan dit?

Is er voor dit probleem geen mooiere oplossing te bedenken (dat lange getal in het programma vind ik geen mooie oplossing)?

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:15
0 * 8 = ........... rarara 0

Initialiseer val op 1 ipv op 0.

[ Voor 37% gewijzigd door whoami op 29-12-2004 15:45 ]

https://fgheysels.github.io/


  • Fatamorgana
  • Registratie: Augustus 2001
  • Laatst online: 21-07-2025

Fatamorgana

Fietsen is gezond.

Ik weet niet of dit in Java werkt. Maar als je bij 0 begint en daarna steeds 1 optelt tot je weer op 0 staat dan ben je helemaal rond geweest. Geen idee of in Java na de max waarde alles weer 0 wordt, maar als dit wel zo is dan kun je dat zo doen.

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Gebruik de constante Long.MAX_VALUE

Verwijderd

Topicstarter
val is op 1 geinitialiseerd, zo slim ben ik ook nog wel.

code:
1
long val=1;


Als je trouwens het getal korter maakt:
code:
1
while (val<223372036854775807L)

gaat het wel goed.

  • Copyman
  • Registratie: Januari 2001
  • Laatst online: 11-05 14:23

Copyman

Dode muis

Misschien zoiets:

Java:
1
2
3
for(long val = 1; val < Long.MAX_VALUE; val*=8) {
    System.out.println("Val=" + val);
}

Rechtstreeks uit http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Long.html

? :)

[ Voor 37% gewijzigd door Copyman op 29-12-2004 16:24 ]

Zeer belangrijke informatie: Inventaris


Verwijderd

Topicstarter
-FoX- schreef op woensdag 29 december 2004 @ 15:48:
Gebruik de constante Long.MAX_VALUE
Bedankt, constanten heb ik nog niet behandeld in het boek.

Maar het werkt niet.

Verwijderd

Topicstarter
Copyman schreef op woensdag 29 december 2004 @ 15:52:
Misschien zoiets:

Java:
1
2
3
for(long val = 1; val < Long.MAX_VALUE; val*8) {
    System.out.println("Val=" + val);
}

Rechtstreeks uit http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Long.html

? :)
Werkt ook niet

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Waarschijnlijk is het probleem dat je Long overflowt ( nederlands woord :? ). Als je bijvoorbeeld een byte hebt die van 0 - 255 loopt en je doet 255 + 1 dan komt daar weer 0 uit ( Hij loopt zeg maar rond ). als je dus 250 * 2 doet wat eigenlijk 500 is komt er 244 uit.
Je zult dus voordat je gaat vermenigvuldigen moeten controleren of de uitkomst groter als de maximale long is.
zoiets als in het volgende voorbeeld
Java:
1
2
3
4
for( long i= 1; i < (Long.MAX_VALUE / 8); i *= 8 )
{
   //doe iets met je i
}

[ Voor 16% gewijzigd door Woy op 29-12-2004 15:59 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Daos
  • Registratie: Oktober 2004
  • Niet online
Misschien moet je na het vermenigvuldigen kijken of uitkomst kleiner is dan begin waarde.

Verwijderd

Topicstarter
Fatamorgana schreef op woensdag 29 december 2004 @ 15:46:
Ik weet niet of dit in Java werkt. Maar als je bij 0 begint en daarna steeds 1 optelt tot je weer op 0 staat dan ben je helemaal rond geweest. Geen idee of in Java na de max waarde alles weer 0 wordt, maar als dit wel zo is dan kun je dat zo doen.
Dat weet ik, zo werkt het in C++.
Maar dat zou niks uit moeten maken, omdat je als de maximale waarde bereikt is (dus voordat val op 0 wordt gezet) al uit de loop bent.

Wacht even, ik bedenk me nu iets. je doet val*=8, stel dat val net onder de maximale waarde zit en er wordt val*=8 uitgevoerd, dan ga je er overheen, dan wordt val=0. dan blijf je in een oneindige loop hangen, want 0*=8 blijft 0.

Verwijderd

Topicstarter
Oke, bedankt iedereen.
Ik weet nu hoe het komt, vanavond of morgen ga ik er weer verder mee en dan zal ik mijn oplossing posten.

  • Copyman
  • Registratie: Januari 2001
  • Laatst online: 11-05 14:23

Copyman

Dode muis

Ik weet niet of dit is wat je bedoelt, maar dit werkt bij mij:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
public void longTest()
{
    long val = 1;
    while(val < Long.MAX_VALUE) {
        if(val != 0) {
            val *= 8;
            System.out.println("Value = " + val);
        }
        else {
            break;
        }
    }
}

[ Voor 3% gewijzigd door Copyman op 29-12-2004 16:06 ]

Zeer belangrijke informatie: Inventaris


  • TlighT
  • Registratie: Mei 2000
  • Laatst online: 22-03 10:40
Deze houdt ook rekening met de overflow:

Java:
1
2
3
4
5
6
7
8
long old,cur=1;
do
{
    System.out.println(cur);
        
    old = cur;
    cur*=8;
} while (cur > old);

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Copyman schreef op woensdag 29 december 2004 @ 16:06:
Ik weet niet of dit is wat je bedoelt, maar dit werkt bij mij:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
public void longTest()
{
    long val = 1;
    while(val < Long.MAX_VALUE) {
        if(val != 0) {
            val *= 8;
            System.out.println("Value = " + val);
        }
        else {
            break;
        }
    }
}
Waarom controleer je niet gewoon voordat je gaat vermenigvuldigen of het gaat overflowen ( weer zo'n goed nederlands woord :? ). Dan werkt he ook nog als je met andere getallen gaat vermenigvuldigen. Dat het op een gegeven moment op 0 uitkomt is alleen toeval omdat je met 2^3 vermenigvuldigd.
ff voorbeeldje met een byte
1 > 8 > 64 > 512 = 256 = 0 > 0 > 0
en als je bv * 7 doet
1 > 7 > 49 > 343 = 87 > 609 = 97 > ...........

Dus dat op 0 controleren is niet echt een mooie oplossing vind ik
TlighT schreef op woensdag 29 december 2004 @ 16:10:
Deze houdt ook rekening met de overflow:

Java:
1
2
3
4
5
6
7
8
long old,cur=1;
do
{
    System.out.println(cur);
        
    old = cur;
    cur*=8;
} while (cur > old);
nee hoor. Want cur hoeft niet altijd groter te zijn als old. Het kan toevallig zo uitkomen dat het andersom is.

Je kan volgens mij echt het best van te voren kijken of je een overflow krijgt of niet.

[ Voor 24% gewijzigd door Woy op 29-12-2004 16:14 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Copyman
  • Registratie: Januari 2001
  • Laatst online: 11-05 14:23

Copyman

Dode muis

@rwb:

Ik weet ook niet precies wat de TS er mee wil doen, en zie er het nut ook niet echt van in. Maargoed, hij weet nu iig dat hij Long.MAX_VALUE kan gebruiken. ;)

Zeer belangrijke informatie: Inventaris


  • TlighT
  • Registratie: Mei 2000
  • Laatst online: 22-03 10:40
rwb schreef op woensdag 29 december 2004 @ 16:12:
nee hoor. Want cur hoeft niet altijd groter te zijn als old. Het kan toevallig zo uitkomen dat het andersom is.
Ja, en daar maakt 'ie dus gebruik van. Zodra er een overflow is, wordt de nieuwe waarde kleiner dan de oude en dan breekt 'ie uit de loop.

Probeer maar, het werkt.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
TlighT schreef op woensdag 29 december 2004 @ 16:18:
[...]

Ja, en daar maakt 'ie dus gebruik van. Zodra er een overflow is, wordt de nieuwe waarde kleiner dan de oude en dan breekt 'ie uit de loop.

Probeer maar, het werkt.
In dit geval wel ja. Maar weer even een voorbeeldje met een byte en een ander getal waarmee je vermenigvuldigd.

stel je zit op 200 en vermenigvuldigd dit met 5. Dan komt er 1000 = 232 uit. Dus dan is de nieuwe waarde alsnog hoger als de oude. Maar je hebt wel een overflow gehad. Dit kan natuurlijk ook met andere waarden voorkomen. Je kan beter iets als dit doen
Java:
1
2
3
4
5
long val = 1;
while( val <= (Long.MAX_VALUE / 8 ) )
{
    val *= 8;
}


en dan kan je voor 8 en voor je initiele waarde elk willekeurig getal invullen en zal het altijd werken.

[ Voor 33% gewijzigd door Woy op 29-12-2004 16:23 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • TlighT
  • Registratie: Mei 2000
  • Laatst online: 22-03 10:40
rwb schreef op woensdag 29 december 2004 @ 16:21:
[...]


In dit geval wel ja. Maar weer even een voorbeeldje met een byte en een ander getal waarmee je vermenigvuldigd.
Dat was niet de vraag.
stel je zit op 200 en vermenigvuldigd dit met 5. Dan komt er 1000 = 232 uit. Dus dan is de nieuwe waarde alsnog hoger als de oude. Maar je hebt wel een overflow gehad. Dit kan natuurlijk ook met andere waarden voorkomen. Je kan beter iets als dit doen
Java:
1
2
3
4
5
long val = 1;
while( val <= (Long.MAX_VALUE / 8 ) )
{
    val *= 8;
}


en dan kan je voor 8 en voor je initiele waarde elk willekeurig getal invullen en zal het altijd werken.
edit: ik zat te suffen :P

[ Voor 13% gewijzigd door TlighT op 29-12-2004 16:48 ]


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Nee het was alleen een opmerking dat die code niet in alle gevallen werkt. Als je het alleen voor dit geval wil dan kan je net zo goed op die 0 controleren.
Dan moet je niet Long.MAX_VALUE / 8 hebben, maar de 8e machts wortel van Long.MAX_VALUE; dat berekenen kan volgens mij niet met de standaard java API want Math.Pow en Math.Log werken alleen op doubles.
Tuurlijk niet als val kleiner of gelijk is aan 1/x e van de MAX_VALUE kan je hem nog met x vermenigvuldigen zonder dat je een overflow krijgt.

met de volgende code kan je dus ook nooit een overflow krijgen
Java:
1
2
3
4
5
6
7
8
public void DoLoop( long initVal, long mul )
{
    long val = initVal;
    while( val <= (Long.MAX_VALUE / mul) )
    {
        val *= mul;
    }
}

[ Voor 17% gewijzigd door Woy op 29-12-2004 16:33 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • TlighT
  • Registratie: Mei 2000
  • Laatst online: 22-03 10:40
rwb schreef op woensdag 29 december 2004 @ 16:29:
[...]
Tuurlijk niet als val kleiner of gelijk is aan 1/x e van de MAX_VALUE kan je hem nog met x vermenigvuldigen zonder dat je een overflow krijgt.
Ow.. he je hebt gelijk - ik antwoordde te snel, ik dacht dat je het aantal stappen berekende :P Jouw oplossing is idd beter.
Pagina: 1