Entier toujours négatif
Tout à l'heure j'ai eu un truc qui m'a paru assez fou : j'avais un plantage en Java sur un simple affichage avec ça :
System.out.println("Value : " + value);
Value était juste un long, mais pendant cet affichage, de temps en temps, ça plantait et ça levait l'exception ArrayIndexOutOfBoundsException... Du coup on a regardé la call stack, et là, surprise, l'exception vient de java.lang.Long.toString... Pour certaines valeurs, la conversion d'un long en String semble tout simplement planter.... J'ai trouvé ça surprenant, mais en fait en regardant le code on est tombé sur un détail que j'ai trouvé très intéressant (d'où ce billet). Ca n'explique en rien le plantage (qu'on a contourné en castant en int...), mais bon.
Voici donc le bout de code en question :
// Is the value negative?
boolean isNeg = num < 0;
...
int i = 0;
char[] buffer;
if (isNeg)
{
num = -num;
// When the value is MIN_VALUE, it overflows when made positive
if (num < 0)
{
i = size = stringSize(MAX_VALUE, radix) + 2;
buffer = new char[size];
buffer[--i] = digits[(int) (-(num + radix) % radix)];
num = -(num / radix);
}
else
{
...
}
...
}
...
On stocke dans isNeg si le nombre est négatif. S'il l'est on fait num = -num... Et on teste si (num < 0) !!! Bon, en fait ça découle d'un truc tout con : les valeurs que peut prendre un entier ne sont pas symétriques. Un entier signé sur 8bit prend en effet les valeurs de -128 à 127... Du coup si on fait -(-128), on obtient à nouveau -128, car ça donne 128, qui ne rentre pas dans le cadre de -128 à 127, et qui overflow en -128.
Ce qui veut dire qu'en pratique, on n'a pas la garantie d'obtenir un nombre positif quand on prend l'inverse d'un nombre négatif... Perturbant ^^ Pas sûr que ça arrive très souvent (sauf dans des cas particuliers genre convertir un entier en chaine de caractères, comme là), mais toujours bon à savoir
Sinon, pour info, l'exception vient de la ligne 16 (buffer[--i]).
Java : fuites mémoires ??
Java, c'est bien, on ne peut pas avoir de fuites mémoires, puisqu'on a un Garbage Collector (GC)... En êtes-vous sûrs ?
Je pose cette question toute conne parce qu'au boulot, dans l'appli Java, on plante au bout d'un moment par manque de mémoire ^^ Alors ça peut paraitre bizarre dit comme ça, mais j'ai commencé à me documenter un peu sur le pourquoi du comment, et je trouve ça assez intéressant.