[java] modulo met getallen groter dan een integer

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

  • Mayco
  • Registratie: Augustus 2002
  • Laatst online: 02-02 18:49
oke, ik zit met iets vreemd vast...

ik heb een bankrekeningnummer die bestaat uit 3 delen, vb 123-1234567-89 waarbij 123 het nummer is van de bank, 1234567 het gebruikersnummer en 89 is de checksum (niet correct hier).

Nu moet die checksum berkend worden aan de hand van de eerste 10 getallen modulo 97.

probleempje: 9999999999 (maximum waarde van de eerste 10 getallen) is groter dan een integer, dus zet ik het in een long, maar dat pakt % niet blijkbaar...

ik krijg deze error:

code:
1
2
3
4
5
6
7
8
possible loss of precision
found   : double
required: int
                this.checkSum = (temp % 97);
                                      ^
1 error

Process completed.


Java:
1
2
3
4
5
6
7
8
9
    public RekeningNummer(int bankDeel, int gebruikersDeel) {
        this.bankDeel = bankDeel;
        this.gebruikersDeel = gebruikersDeel;
        
        double temp = (double)bankDeel*10000000+gebruikersDeel;
        
        System.out.println(temp); // dit geeft wel het goede resultaat (de eerste 10 getallen), dit was negatief als temp een int is
        this.checkSum = (temp % 97);
    }


code:
1
2
3
4
5
bankdeel: 789
gebruikesdeel: 9871234
samen: 7899871234
checksum: -23 (wat dus fout is!)
789 - 9871234 - -23


moet ik ergens rekening mee houden of bestaat er een % die werkt met getallen groter dan 2147483647?

  • Swaptor
  • Registratie: Mei 2003
  • Laatst online: 16-02 22:21

Swaptor

Java Apprentice

Een oplossing die ik je kan geven, is het zelf implementeren van een modulo-operatie.

Aangezien een modulo alleen uitgevoerd kan worden op een integer, en niet op een getal met een komma er in (long) ben je in dit geval veroordeeld tot het zelf schrijven.



Wat ook kan, is het gebruiken van Math.BigInteger, die ondersteunt ook de mod()-functie.

http://java.sun.com/j2se/...java/math/BigInteger.html

[ Voor 26% gewijzigd door Swaptor op 06-05-2006 12:42 . Reden: Meer info. ]

Ontdek mij!
Proud NGS member
Stats-mod & forum-dude


  • MetroidPrime
  • Registratie: Oktober 2003
  • Laatst online: 25-01 09:16

MetroidPrime

Turn it up loud, captain!

Je zou de BigInteger class kunnen gebruiken, deze kan met abritrary precision nummers omgaan:
[code=java]
BigInteger temp = new BigInteger(bankDeel).multiply("10000000").add(gebruikersDeel).mod(97);
this.checksum = temp.intValue();
[/code]

EDIT: Ik was nog niet helemaal wakker. Een long zou inderdaad ook moeten kunnen en zou een betere oplossing zijn dan het gebruik van een BigInteger.

[ Voor 29% gewijzigd door MetroidPrime op 06-05-2006 13:40 ]

"Some girl on the street outside the bar just asked me if I was saved yet." "Yeah? What did you say?" "I told her 'I saved at the checkpoint a couple of minutes back and I can reload from there if I die.'


  • BestTested!
  • Registratie: Oktober 2003
  • Laatst online: 20:34
Swaptor schreef op zaterdag 06 mei 2006 @ 12:37:
Een oplossing die ik je kan geven, is het zelf implementeren van een modulo-operatie.

Aangezien een modulo alleen uitgevoerd kan worden op een integer, en niet op een getal met een komma er in (long) ben je in dit geval veroordeeld tot het zelf schrijven.



Wat ook kan, is het gebruiken van Math.BigInteger, die ondersteunt ook de mod()-functie.

http://java.sun.com/j2se/...java/math/BigInteger.html
Bij mij werkt het gewoon: Windows Calculator zegt ook 47
Java:
1
2
3
4
5
6
    public static void main(String[] args)
    {
        long value = 7899871234L;       
        long moduloValue = (value % 97);
        System.out.println (moduloValue); //anwser=47
    }

  • Nick The Heazk
  • Registratie: Maart 2004
  • Laatst online: 07-09-2024

Nick The Heazk

Zie jij er wat in?

Ik wil toch even opmerken dat het gebruik van double precision floating-point getallen niet aan te raden is in jou geval (voor zover ik hier zicht op heb in de code). Er treden namelijk snel afrondingsfouten op, zeker als je met zulke grote verschillen tussen de getallen zit.

Indien je enkel met gehele getallen wilt werken, zou je best gebruikmaken van longs of ints. Indien deze geen voldoende groot bereik hebben, is de reeds vermeldde klasse Java.Math.BigInteger de beste oplossing.

Wat er in jou code misgaat is het volgende: de modulo-operator is niet gespecifieerd voor doubles. Jij doet dit:
code:
1
long = double % int


Maar dat is niet toegestaan. Je kunt de modulo-operator enkel toepassen op ints of longs. Dus:
code:
1
long = long % int
. In jou code kun je dat dus oplossen door temp te typecasten naar een long. Ik raad je dit echter niet aan. Je kunt beter werken met longs.

[ Voor 30% gewijzigd door Nick The Heazk op 06-05-2006 13:59 ]

Performance is a residue of good design.


  • Mayco
  • Registratie: Augustus 2002
  • Laatst online: 02-02 18:49
Java:
1
        this.checkSum = (int)(((long)bankDeel*10000000+gebruikersDeel) % 97);

Dit was de sleutel tot succes... blijkbaar moest ik bankDeel nog expliciet casten naar een long, en achteraf het hele goedje weer naar int.

Bedankt voor de reacties!
Pagina: 1