Probléme avec les tableaux de byte de taille fixe

[Fermé]
Signaler
Messages postés
7
Date d'inscription
jeudi 25 juin 2015
Statut
Membre
Dernière intervention
26 juin 2015
-
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
-
Bonjour,

j'ai un problème au niveau d'affectation dans un tableaux, j'essaye maintenant d'implémenter une méthode pour générer deux tableaux LogTable and AntiLogTable pour le corps fini de Galois, voila le code:

static void generate_tables() {
  ArrayList<Byte> antiLogTable = new ArrayList<Byte>(256);
  ArrayList<Byte> logTable = new ArrayList<Byte>(256);
  logTable.add(0,(byte)0);
  //antiLogTable = new byte[256];
  
  //logTable = new byte[256];
   
      short c;
      byte a = 1;
      byte d;
      for(c=0;c<256;c++) {
             antiLogTable.add((byte) a);
             
             //[c] = (byte) a;
             
             
             /* Multiply by three */
             d =   (byte) (a & 0x80);
             a <<= 1;
             if(d != 0) {
                     a ^= 0x1b;
             }
             a ^= antiLogTable.get(c);
             
        /* Set the log table value */
             
             System.out.println(antiLogTable.get(c));
             
             logTable.add(Byte2Short(antiLogTable.get(c)),Short2Byte(c));
             //logTable[Byte2Short(antiLogTable[c])]=Short2Byte(c);
             
             
             //ltable[atable[c]] = c;
            // System.out.print(Byte2Short(antiLogTable[c])+",");
             
             System.out.println(Byte2Short(antiLogTable.get(c))+":"+Short2Byte(c)+":"+Byte2Short(logTable.get(c))+",");
            
     }
     antiLogTable.add(antiLogTable.get(0));
     logTable.add(0,(byte) 0);
}



mon probléme ce se pose au niveau de cette partie:
//logTable[Byte2Short(antiLogTable[c])]=Short2Byte(c);


lorsque la boucle ou l'indice c dépasse l'indexe du logTable par exemple c = 25 et je veux affecter une valeur à la case 2 du log table, cela ça ne marche pas je pense que le problème est au niveau de gestion de mémoire, alors je cherche une autre solution, j'ai essayé comme vous avez vu sur le code le ArrayList mais aussi ce dernier est un tableau dynamique alors du coup je reçois des exception: IndexOutOfBounds, c'est logique parce que l'arraylist doit étre initialiser à l'avance.

Merci de me donner quelques Idée sur comment faire, j'ai passé deja une journnée en essayant de trouver une sol.

NB: je travail sur lo mobile phone, alors j'ai ignoré les solutions couteuses en terme de mémoire ou CPU.

Grand Merci

2 réponses

Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 861
Bonjour,

"j'ai ignoré les solutions couteuses en terme de mémoire ou CPU"
ArrayList<Byte> est alors un très mauvais choix en terme de consommation mémoire, en comparaison d'un byte[] par exemple.

De plus quel intérêt d'avoir des méthodes Byte2Short et Short2Byte alors que ce sont deux types de données interchangeables (au cast près) ?

Quant à ton problème c'est que tu as l'air de penser que
new ArrayList<Byte>(256)
va créer une liste de 256 éléments, alors qu'en fait la liste est vide au départ, c'est la capacité de la liste (sa taille interne) qui est réservée à 256.
Donc quand tu fais un get(3) alors que la liste n'a que 2 éléments, forcément ça plante.
Messages postés
7
Date d'inscription
jeudi 25 juin 2015
Statut
Membre
Dernière intervention
26 juin 2015

1- oui "c'est juste que tu accèdes à un élément qui n'existe pas. " ça je le sais deja.
2- je ne sais qu'est ce que tu veux dire avec ça " byte c'est un faux problème, quand on voit que tu utilises des Byte de 16 octets", alors qu'un byte est = 1 octet .... un short = 2, alors que le stockage du 2eme est inutile si j'en ai besoin seulement de 8 bits.

3- mon problème est clair dans cette ligne du code (obliant les arrayList c'est juste un essai).

logTable[Byte2Short(antiLogTable[c])]=Short2Byte(c);

c'est simple on peut l'appeler une insertion aléatoire dans un tableau fixe. Alors lorsque le compteur c dépasse une certaine valeur ex 20 alors je ne peux pas revenir en arrière et affecter une valeur dans la case exemple 2.
Messages postés
7
Date d'inscription
jeudi 25 juin 2015
Statut
Membre
Dernière intervention
26 juin 2015

enfin le problémes est résolu avec le hashMap<short, byte> mais je ne sais pas si cette solution est optimisé ou non.
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 861
"un byte est = 1 octet .... un short = 2"
Oui un byte (type primitif) fait 1 octet, mais 1 Byte (objet) en fait 16, et il faut également rajouter la taille de la liste d'objet qui est bien plus lourde qu'un tableau de type primitif.

Taille d'un byte[n] : n+19 octets
Taille d'un ArrayList<Byte>(n) remplie : 20*n+34 octets

Remarque : 1 objet fait 15 octets (empirique) sur mon ordinateur, cela peut varier d'une version à l'autre de Java, en particulier sur mobile.

Tu auras le même problème avec les Map, car elles manipulent aussi des objets, donc des Byte, et pas des byte.

L'optimal en consommation mémoire reste bien sûr le byte[], mais vu les transitions de byte vers short que tu fais, ça nuit à ta vitesse.
En comparaison un short[n] fait 2n+19 octets, c'est 10 fois moins qu'un ArrayList<Byte>, et tu n'as aucune conversion à faire.
Messages postés
7
Date d'inscription
jeudi 25 juin 2015
Statut
Membre
Dernière intervention
26 juin 2015

bien compris Merci, en faite c'est pour cela j'essaye de trouver une solution en utilisant seulement un tableau simple de byte.

"un short[n] fait 2n+19 octets, c'est 10 fois moins qu'un ArrayList<Byte>" t'as raison pour, c'était juste un essai, pareil pour le hashMap malgré que ça marche, je ne suis pas trés satisfait.

on laissons ça à coté, le probléme reste toujours, même si j'utilise une matrice des entiers.

je reviens à ma question de base, comment faire une insertion dans des cases de vecteur simple (Byte, short, int ....), aléatoirement choisies(ie: 2, 50, 5, 255, 62, 3, 89 .....).

au pire quelle la meilleur façon de le faire s'il n 'ya pas de solution simple.
Messages postés
7
Date d'inscription
jeudi 25 juin 2015
Statut
Membre
Dernière intervention
26 juin 2015

ce que j'en ai besoin vraiment est une façon pour dire aux index du vecteur logTable de revenir au départ après chaque affectation, comme ça le suivant même si l'index est inférieur l'insertion s'effectue normalement, par ce que l'écriture dans un vecteur de tel genre s'effectue de façon séquentielle.
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 861
Bon, je ne suis pas bien sûr d'avoir compris le but du programme, dans un premier temps j'utilise des short pour permettre de ne pas trop s'embêter avec les byte négatifs, c'est juste le temps de mettre en place les tableaux, car ce sera le plus efficace.

Quelques remarques au passage :

Si tu veux optimiser la consommation mémoire, déclares tes variables au dernier moment, au plus près du code où tu l'utilises, ça éviteras d'avoir à la mettre en mémoire à un moment où tu n'en as pas encore besoin, et de la libérer dès qu'elle n'a plus lieu d'être.

Je sais pas exactement ce que tu as voulu faire avec le code suivant, mais s'il s'agit vraiment d'une multiplication de deux bytes, je laisserai Java s'en occuper tout seul, le processeur sait gérer nativement la multiplication d'entiers, pas besoin de lui refaire programmatiquement.

// Multiply by three
byte d = (byte) (a & 0x80);
a <<= 1;
if (d != 0) {
    a ^= 0x1b;
}
a ^= antiLogTable.get(c);

Si tu fais des concaténations de String, tu vas perdre de la mémoire car les String ne sont jamais modifiés, un nouveau String est créé pour obtenir le résultat de la concaténation. Si tu fais
alt+":"+c+":"+lt+","
tu auras donc des String intermédiaires pour
alt+":"
,
alt+":"+c
,
alt+":"+c+":"
,
alt+":"+c+":"+lt
et
alt+":"+c+":"+lt+","
ça commence à faire pas mal de perte de mémoire juste pour un affichage...

Et enfin, comme tu fais des ajouts add(i,x) avec ArrayList j'ai supposé que tu voulais insérer des éléments (exemple
[1,2,3,4].add(2, 5)=[1,2,5,3,4]
), mais du coup je ne comprends pas tes affichages puisqu'ils affichent l'ordre au fur et à mesure en sachant qu'il va être modifié par la suite...

Bref, pas mal d'incompréhension sur ton code actuel et ton objectif pour t'aider, et tes dernières explications ne m'aident pas beaucoup, c'est assez confus.

Voici une version avec des tableaux plutôt que des listes, mais le résultat est à mon avis très loin de ce que tu attends... peut-être qu'en expliquant plus clairement ton problème on pourrait repartir de zéro avec ton code et que ce serait plus proche de ce que tu souhaites.

static void generate_tables() {
    short[] antiLogTable = new short[256];
    short antiLogTableSize = 0;

    short[] logTable = new short[256];
    short logTableSize = 0;

    // add(0,0)
    logTableSize++;
    logTable[0] = 0;

    short a = 1;
    for (short c = 0; c < 255; c++) {
        // add(a)
        antiLogTable[antiLogTableSize++] = a;

        // Multiply by three ???
        a = (short) ((3 * a) % 256);
        /*
         * short d = (short) (a & 0x80); a <<= 1; if (d != 0) { a ^= 0x1b; } a ^= antiLogTable[c];
         */

        System.out.println(antiLogTable[c]);

        // add(c, c)
        for (short s = logTableSize; s > c; s--)
            logTable[s] = logTable[s - 1];
        logTable[c] = c;
        logTableSize++;

        System.out.print(antiLogTable[c]);
        System.out.print(':');
        System.out.print(c);
        System.out.print(':');
        System.out.print(logTable[c]);
        System.out.println(',');

    }

    // add(anti[0])
    antiLogTable[antiLogTableSize++] = antiLogTable[0];

    // add(0,0)
    for (short s = 255; s > 0; s--)
        logTable[s] = logTable[s - 1];
    logTable[0] = 0;
    logTableSize++;

    System.out.println(Arrays.toString(logTable));
    System.out.println(Arrays.toString(antiLogTable));
}