2015-11-12 1 views
2

en faisant quelques exercices dans Lua, je suis tombé sur un comportement (étrange) à mon sens que je ne peux pas expliquer. Le code suivant est censé calculer le nombre de termes distincts de la forme a^b pour 2 < = a, b = 100. < Ce code fournit la bonne réponse, 9183:Comportement inexpliqué lors du calcul de grandes puissances dans Lua

local terms = {} 
local cnt = 0 
for a = 2, 100 do 
    for b = 2, 100 do 
    term = math.pow(a, b) 
    if not terms[term] then 
     terms[term] = string.format("%d exp %d", a, b) 
     cnt = cnt + 1 
    else 
     print(term .. " already in set! (" .. terms[term] .. ")") 
    end 
    end 
end 

print(cnt) 

Cependant, ce code produit une réponse différente (seule la 'impression()' dans la branche else est commenté):

local terms = {} 
local cnt = 0 
for a = 2, 100 do 
    for b = 2, 100 do 
    term = math.pow(a, b) 
    if not terms[term] then 
     terms[term] = string.format("%d exp %d", a, b) 
     cnt = cnt + 1 
    else 
     --print(term .. " already in set! (" .. terms[term] .. ")") 
    end 
    end 
end 

print(cnt) 

Il. cela me donne 9254 comme réponse. Il n'y a aucun calcul effectué dans cette ligne commentée, juste sortie à l'écran. Pourtant, il semble influencer le résultat du calcul. Ai-je découvert un système macroscopique qui sous-tend les lois de la mécanique quantique? Non, mais sérieusement, il me manque quelque chose ici, et je serais très reconnaissant si quelqu'un avec plus d'expérience et de connaissances pouvait me diriger dans la bonne direction.

Merci d'avance!

+0

Peut-être devriez-vous demander sur une liste ou un forum Lua ... –

+0

Oui, je suppose que vous avez raison . Je vais attendre un jour ou deux. Si après cela personne ne donne une réponse plus précise, je choisirai votre réponse, car elle m'a apporté un aperçu et un excellent site web que je peux lire et ensuite diffuser. –

+0

Quelle version de Lua? Quel compilateur C? Quel système d'exploitation? Comment Lua a-t-il été configuré et compilé? –

Répondre

1

Les nombres Lua sont généralement floating point. Sur la plupart des machines, cela signifie pratiquement double en langage C99 qui sont représentés par IEEE 754 nombres à virgule flottante.

Vous devez lire http://floating-point-gui.de/ (le point flottant est un mal de tête).

En particulier, les tables Lua calculent du hachage et testent l'égalité, et l'égalité à virgule flottante est pas égalité sur les nombres réels mathématiques. Par conséquent, l'utilisation de nombres à virgule flottante comme clé pour les tables est risquée.

Un grand nombre comme 98 sont non représentésexactement IEEE 754 ...

Moralement, si vous utilisez un numéro comme clé pour une table de Lua, vous avez mieux que nombre entier soit un peu avec précision représentable dans IEEE754, alors soyez concrètement un nombre entier inférieur à 2

Je suppose que vous avez été mordu par un artefact spécifique de mise en œuvre. Vous pouvez déboguer le code Lua C (c'est-à-dire, étape par étape, dans l'implémentation de Lua C) pour en savoir plus. Peut-être que certains garbage collection, ou simplement la table de hachage, se passe dans le premier programme, mais pas dans le second, ou dans différentes règles d'arrondis ...

BTW, sur mon bureau Linux/Debian/Sid/x86-64 avec Debian a empaqueté Lua 5.2.4-1 et avec Debian empaqueté Lua 5.3.1-1, les deux programmes donnent 9183.

+0

Hey, merci beaucoup! Je soupçonnais déjà le problème d'avoir quelque chose à voir avec les FPN, mais je ne comprends toujours pas pourquoi le premier exemple de code _always_ m'obtient la bonne réponse alors que le deuxième exemple _always_ m'obtient la (mauvaise) réponse. (Excellent site Web, au fait, ne le savais pas, merci!) –

+0

Choisir cette réponse. Avec les commentaires à la question, @BasileStarynkevitch, vous m'avez donné une idée assez décente de ce qui se passe. –