fredag den 9. september 2011

Overskridelse af integerstørrelse i java


Her er  lidt tanker om hvad der sker når man overskrider grænsen for et tal, fx adderer to tal, som giver en integer der burde fylde mere end de 32bit, eller 4 bytes, der er grænsen for en integer i java. Jeg har desværre ikke kunne finde nogen dokumentation, så tag det med et gran salt og kom gerne med rettelser eller tilføjelser.



Først skal vi forestille os en datatype som integeren der dog kun er 4 bit lang. Den kan altså indeholde fire et'er og nul'er startende med 0000 der svarer til integeren 1, 0001=1, 0010=2, 0011=3, 0100=4... -> 1111=2^4=15. Lad os nu betragte vores korte integer med værdien 15 (1111) og addere 1. Vi burde få det binære tal 10000, men der afrundes til 0000 da datatypen kun har 4 bits.

Dette princip er gældende for addition af integers i java, der er 32 bit og altså kan indeholde +/- 2^31 tal. Grunden til at det kun er ^31 i stedet for ^32 er fordi (dette er min teori) at det første binære tal afgør fortegnet. 2^31=Math.pow(2, 31) hvilket i binære tal vil være 1 efterfulgt af 31 1'er. Når vi adderer 1 til 2^31 vil vi få 1 efterfulgt af 32 1'er hvilket ændrer fortegns bit'en der er den første af de 32 bit.
Vi har nu 2^31+1=-2^31 (2^31 har en numerisk værdi der er 1 mindre end -2^31 da nul er et tal)

Her følger lidt kode der efterviser påstanden, leg selv lidt med det:

public class IntLimits {

            public static void main(String[] args) {
                  //De fornødne primitive typer initialiseres
                  int a, b;
                  double c;

                  /* a defineres til 2 da vi regner binært 
                  * og a^31 gemmes som double da Math.pow kræver det
                  * Derefter gemmes c som  int  b da det er dennes længde 32 bit vi leger med
                  */ 
                  a = 2;
                  c = Math.pow(a, 31);
                  b = (int) c;
                  System.out.println(b);
                  System.out.println(b+1);
             }
}

Resultat af udskrift:

2147483647
-2147483648

Ingen kommentarer:

Send en kommentar