Mais une question que j'avais posée est : qu'est-ce qui peut pousser un développeur à utiliser cette fonction en dehors des bornes 0 .. 63 ?
A cette question je pourrais répondre bêtement en disant que je veux que la fonction suivante calcule le quotient de n par 2^a pour toutes les valeurs de la plage des types de ses arguments.
functionquo_power2(n,a: natural)returnnatural;
Mais je vais préfère t'expliquer dans quel contexte moins artificiel on peut avoir besoin d'un décalage supérieur ou égal à 64 en te décrivant une petite partie du projet de mes étudiants.
Description partielle du projet
Celui-ci consiste à coder les opérations + et \times sur le type "double" en n'utilisant que des opérations sur les entiers unsigned sur 64 bits (les qword en Pascal). Autrement dit jouer avec la norme IEEE754 qui décrit la représentation des flottants en machine ainsi que les opérations standard sur ces flottants. Cela permet vraiment de comprendre en profondeur qu'une machine ne sait vraiment pas manipuler correctement les réels (contrairement à ce qu'ils croient tous).
Description de la représentation machine des « double »
Grosso modo, cette norme stipule qu'un double est un espace mémoire sur 64 bits organisé, de gauche à droite, de la façon suivante: 1 bit de signe (s) , 11 bits d'exposant (e) et 52 bits de mantisse (k). Le réel correspondant à cet espace mémoire est alors \left(-1\right)^{s}2^{e-1023}\left(1+k2^{-52}\right). Donc déjà, une remarque, il faut un langage permettant de lire un même espace mémoire avec deux typages différents (double et qword) donc, adieu Python.
Addition machine des « double »
Je ne vais pas traiter tous les cas mais celui qui a fait apparaître le fameux problème dont on discute : l'addition de x et y (x>y>0). Je note k et k' les mantisses entières respectives de x et y, e et e' leurs exposants.
Un petit calcul montre que l'exposant de la somme est le max des deux exposants (éventuellement + 1) . Pour le calcul de la mantisse on a nécessairement, à un moment donné, k+2^{e'-e}k'. Vu que e'-e<0, cela revient à diviser k' par une puissance de deux comprise entre 0 et 2046. Donc à faire un shr sur k' d'un amount compris entre 0 et 2046.
Sauf que voilà, pour une raison d'optimisation qui leur était totalement inconnue, le comportement arithmétique de cette opération redevient identique modulo 64 et patatra !
Quand j'ai préparé le projet chez moi, en Ada, je n'ai vu aucun problème car Ada ne reproduit pas les optimisations de bas niveau en cassant l'arithmétique. Le compilateur FreePascal lui, reproduit ce comportement arithmétique incohérent et sa doc ne dit rien à ce sujet.
[^] # Re: Du haut niveau pour gérer correctement du bas niveau
Posté par snowball (site web personnel) . En réponse au journal Un décalage de 64 bits, ça vous inspire comment ?. Évalué à 1.
A cette question je pourrais répondre bêtement en disant que je veux que la fonction suivante calcule le quotient de n par 2^a pour toutes les valeurs de la plage des types de ses arguments.
Mais je vais préfère t'expliquer dans quel contexte moins artificiel on peut avoir besoin d'un décalage supérieur ou égal à 64 en te décrivant une petite partie du projet de mes étudiants.
Description partielle du projet
Celui-ci consiste à coder les opérations + et \times sur le type "double" en n'utilisant que des opérations sur les entiers unsigned sur 64 bits (les qword en Pascal). Autrement dit jouer avec la norme IEEE754 qui décrit la représentation des flottants en machine ainsi que les opérations standard sur ces flottants. Cela permet vraiment de comprendre en profondeur qu'une machine ne sait vraiment pas manipuler correctement les réels (contrairement à ce qu'ils croient tous).
Description de la représentation machine des « double »
Grosso modo, cette norme stipule qu'un double est un espace mémoire sur 64 bits organisé, de gauche à droite, de la façon suivante: 1 bit de signe (s) , 11 bits d'exposant (e) et 52 bits de mantisse (k). Le réel correspondant à cet espace mémoire est alors \left(-1\right)^{s}2^{e-1023}\left(1+k2^{-52}\right). Donc déjà, une remarque, il faut un langage permettant de lire un même espace mémoire avec deux typages différents (double et qword) donc, adieu Python.
Addition machine des « double »
Je ne vais pas traiter tous les cas mais celui qui a fait apparaître le fameux problème dont on discute : l'addition de x et y (x>y>0). Je note k et k' les mantisses entières respectives de x et y, e et e' leurs exposants.
Un petit calcul montre que l'exposant de la somme est le max des deux exposants (éventuellement + 1) . Pour le calcul de la mantisse on a nécessairement, à un moment donné, k+2^{e'-e}k'. Vu que e'-e<0, cela revient à diviser k' par une puissance de deux comprise entre 0 et 2046. Donc à faire un shr sur k' d'un amount compris entre 0 et 2046.
Sauf que voilà, pour une raison d'optimisation qui leur était totalement inconnue, le comportement arithmétique de cette opération redevient identique modulo 64 et patatra !
Quand j'ai préparé le projet chez moi, en Ada, je n'ai vu aucun problème car Ada ne reproduit pas les optimisations de bas niveau en cassant l'arithmétique. Le compilateur FreePascal lui, reproduit ce comportement arithmétique incohérent et sa doc ne dit rien à ce sujet.