Je me demande si cela est vrai: lorsque je prends la racine carrée d'un entier carré, comme dans
100_000_000.times do |i| puts i if Math.sqrt(i*i).floor != i end
4 Réponses :
pour "petit" entiers, il existe généralement une représentation exacte du point flottant. P>
Oui. La représentation des points flottants est exacte pour tous les entiers ayant moins de bits significatifs que la mantissie de la représentation du point flottant: 23 bits pour une précision unique, 52 pour le double si nous parlons de IEEE 754. Grâce à un meneur implicite 1 dans la Mantissa, C'est en fait 24 et 53.
+1: En règle générale, pensez aux flotteurs comme ayant 48 bits de précision utiles. (Les tailles réelles varient, mais vous pouvez travailler avec 48 en règle générale). Afin d'accéder à un endroit où le dernier bit importe réellement, vous devez travailler avec un produit d'INT qui a une taille d'au moins 48 bits.
Merci, tu as raison. Il commence à arrêter de travailler au 9007199254740993, ce qui est 2 ^ 53 + 1 code>
Woo Hoo, merci de vérifier! S.Lott m'avait inquiet pendant un moment! :)
Il n'est pas trop difficile de trouver des cas où cela se décompose comme prévu:
Math.sqrt(94949493295293425**2).floor # => 94949493295293424 Math.sqrt(94949493295293426**2).floor # => 94949493295293424 Math.sqrt(94949493295293427**2).floor # => 94949493295293424
Et math.sqrt (94949493295293423 ** 2) .floor code> ==>
94949493295293424 code>, aussi.
Le flotteur de Ruby est un numéro de point flottant à double précision, ce qui signifie qu'il peut représenter avec précision des nombres avec (règle de point de pouce) environ 16 chiffres décimaux significatifs. Pour les nombres de points flottants réguliers de la précision unique, il s'agit de 7 chiffres significatifs. P>
Vous pouvez trouver plus d'informations ici: P>
Quel est ce que chaque informatique doit savoir sur l'arithmétique de points flottants: http://docs.sun.com/source/819-3693/ncg_goldberg. HTML P>
Voici l'essence de votre confusion:
en raison de la représentation des points flottants précision, cela pourrait être quelque chose comme 122.9999999999999999999999 ou 123.00000000000000000000001. P> BlockQuote>
Ceci est faux. Ce sera toujours exactement 123 sur un système compatible IEEE-754, qui constitue presque tous les systèmes de ces temps modernes. L'arithmétique à virgule flottante n'a pas de "erreur aléatoire" ou de "bruit". Il a un arrondi précis, déterministe et de nombreux calculs simples (comme celui-ci) n'entraînent aucun arrondi. P>
123 code> est exactement représentable dans le point flottant, et c'est ainsi que
123 * 123 CODE> (Ainsi sont tous les entiers de taille modeste em> Donc, aucune erreur d'arrondi ne se produit lorsque vous convertissez
123 * 123 code> sur un type à virgule flottante. Le résultat est exactement fort>
15129 code>. P>
la racine carrée est une opération correctement arrondie em> par la norme IEEE-754. Cela signifie que s'il y a une réponse exacte, la fonction racine carrée est nécessaire pour la produire. Puisque vous prenez la racine carrée de exactement em>
15129 code>, qui est exactement em>
123 code>, c'est exactement < / em> le résultat obtenu de la fonction racine carrée. Aucun arrondi ou approximation ne se produit. P>
Maintenant, pour la taille d'un entier cela sera vrai? P>
double précision peut représenter tous les entiers jusqu'à 2 ^ 53. Ainsi, aussi longtemps que
i * i code> est inférieur à 2 ^ 53, aucun arrondi ne se produira dans votre calcul, et le résultat sera exact pour cette raison. Cela signifie que pour tous
i code> plus petit que
94906265 code>, nous savons que le calcul sera exact. P>
mais vous avez essayé
i code> Plus grand que ça! Qu'est-ce qui se passe? P>
pour le plus grand
i code> que vous avez essayé,
i * i code> est juste à peine plus grand que 2 ^ 53 (
1.1102 .. . * 2 ^ 53 code>, en fait). Parce que les conversions d'entier à double (ou multiplication en double) sont également correctement arrondies em> les opérations,
i * i code> sera la valeur représentable la plus proche du carré exact de
i code>. Dans ce cas, étant donné que
i * i code> est de 54 bits de large, l'arrondi se produira au plus bas bit. Ainsi, nous savons que: p>
xxx pré> où
arrondi code> est soit
-1,0, ou 1 code>. Si l'arrondi est zéro, le carré est exact, de sorte que la racine carrée est exacte, donc nous savons déjà que vous obtenez la bonne réponse. Ignorons ce cas. P>
Alors maintenant, nous regardons la racine carrée de
i * i * i +/- 1 code>. Utilisation d'une expansion de la série Taylor, la valeur infiniment précise (non heurée) de cette racine carrée est la suivante: p>
xxx pré> C'est un peu fidèle à voir si vous n'avez fait aucun flottant Analyse des erreurs de point Auparavant, mais si vous utilisez le fait que
i ^ 2> 2 ^ 53 code>, vous pouvez voir que le: p>
xxx pré> terme est plus petit que 2 ^ -54, ce qui signifie que (car la racine carrée est correctement arrondie et que son erreur arrondi doit être inférieure à 2 ^ 54), le résultat arrondi em> de la fonction SQRT est exactement
i code>. p>
Il s'avère que (avec une analyse similaire), pour tout numéro de point flottant représentable X, sqrt (x * x) est exactement x (en supposant que le calcul intermédiaire de
x * x code> ne pas trop ou sous le flux de flux), de sorte que la seule façon de rencontrer l'arrondi pour ce type de calcul est dans la représentation de
x code> lui-même, c'est pourquoi Vous le voyez à partir de
2 ^ 53 + 1 code> (le plus petit entier non représentable). P> P>
Wow. Traitement très complet (et précis), +1.
Vous pouvez changer
i = 0; 100000000.time {met i; i + = 1} code> à
100000000.time {| i | met i} code>
Droite, merci. c'est un peu plus simple maintenant