2016-12-17 4 views
0

Je programmation avoir une simple question .. Je ce code:mathématiques et dans physic

program wtf; 
var i:integer; 
begin 
    for i:=1 to 20 do 
     if sqrt(i)*sqrt(i)<>i then writeln(i); 
    readln 
end.  

... il passe par la boucle 20 fois et pour les nombres de 1 à 20 et il vérifie si racine carrée multipliée acheter racine carrée de même nombre est égale à ce nombre. Si nous utilisons des règles mathématiques ce programme ne devrait jamais avoir quoi que ce soit sur la sortie, mais .... Je ça:

2 
3 
5 
6 
7 
8 
10 
12 
13 
15 
18 
19 
20 

peut sombody expliquer ce qui se passe?

+0

Lorsque vous utilisez des flottants, sur un ordinateur, vous ne pouvez pas comparer les valeurs et attendre une égalité absolue. Vous devez utiliser une comparaison de différence de seuil. les flotteurs ne sont pas utilisés pour *** compter *** les choses, ils sont utilisés pour *** mesurer *** les choses. Deux valeurs mesurées ne sont jamais *** exactement *** la même chose. ils sont seulement "assez proches". –

+0

Ce n'est pas un modèle mental très productif. Le moyen le plus utile de penser à cela est que toutes les valeurs ne peuvent pas être représentées exactement. –

+0

Vous ne pouvez pas représenter 0.1 exactement en binaire plus que 1/3 en décimal. – duffymo

Répondre

2

Ceci est dû à la précision. La racine carrée d'un nombre qui n'est pas un carré parfait donnera un nombre irrationnel, qui ne peut pas être représenté correctement en mémoire en utilisant l'arithmétique en virgule flottante. Au lieu de cela, le nombre est tronqué après quelques chiffres (en binaire, mais le concept est le même qu'en décimal).

Le nombre est maintenant très proche, mais pas tout à fait, de la racine carrée du nombre d'origine. La quadrature va produire un nombre qui est très proche de l'original, mais pas tout à fait. Imaginez-vous cela, la racine carrée de 2 est 1.4142135623........(etc.) mais elle est coupée à 1.414213 pour des raisons de mémoire. 1.414213 * 1.414213 = 1.99999840937 et non 2.

Cependant, la racine carrée de 4 est 2, et elle peut être entièrement stockée en mémoire, sans être coupée après quelques décimales. Lorsque vous faites ensuite 2 * 2 vous obtenez exactement 4.

Parfois, le nombre peut être coupé, mais lors de l'équerrage, il est encore assez proche pour produire la valeur d'origine. C'est pourquoi 11 ne s'affiche pas.

+0

Ha vous pensez vraiment que je n'ai pas pensé à cela xd – anakata

+0

Ce n'est pas tout à fait vrai couse dans la sortie ... il n'y a pas 11 ou même 1 – anakata

+0

Vous avez raison, je vais modifier ma réponse – Max

1

sqrt génère des nombres à virgule flottante. Lorsque vous utilisez des flottants, sur un ordinateur, vous ne pouvez pas comparer les valeurs et attendre une égalité absolue. Vous devez utiliser une comparaison de différence de seuil. flotteurs ne sont pas utilisés pour compter choses, ils sont utilisés pour mesure choses, (pour compter les choses, utiliser des nombres entiers) ,. Non deux mesuré (même dans le monde réel) les valeurs sont toujours exactement le même. ils sont seulement "assez proches".

Sur un ordinateur, il est impossible de représenter tous les nombres réels possibles. SO chaque valeur calculée est représentée par le nombre "le plus proche" dans l'ensemble des nombres possibles, (pour ce type de données), qui peut être représenté sur l'ordinateur. Cela signifie qu'il est très légèrement incorrect, et donc après quelques calculs, il ne se conformera pas à des comparaisons d'égalité parfaites. `Sqrt` génère des nombres à virgule flottante

+0

Si oui, pourquoi n'y a-t-il pas 1 et 11? – anakata

+0

Je ne peux pas répondre à '11' mais' 1' est un nombre carré. Sa racine carrée est '1'. Il peut être stocké correctement. – Max

+0

Mon mauvais pour 1 mais je ne pense pas que c'est la solution pour mon problème – anakata