Questions de débordement sur flotteurs et les flotteurs entiers de
-
27-09-2019 - |
Question
1) Est-ce unoverflowable?
long long v1, v2, result;
[..]
result = ((long double) v1 / v2) * 1000000LL;
1.a) Puis-je quitter le LL sur la constante? Et pourquoi.
2) est Sinon cette variation sans ok flottante?
long long l1, l2, result;
[..]
result = (1000000 * (v1 / v2) + v1 % v2);
2.a) qui a plus les frais généraux? Le 1er ou cet exemple?
3) peut flotte toujours débordement, ou tout simplement envelopper les valeurs « de saines »?
La solution
Oui, le résultat dans l'exemple (1) pourrait facilement déborder si, par exemple, v1 et v2 = 1000000000000000 = 1. Vous n'avez pas besoin LL à cette constante, car il est assez petit pour tenir dans un int
(dans la plupart mises en oeuvre, dans tous les cas).
(2) Cela peut déborder aussi bien que l'exemple 1 si v1 et v2 sont comme je les ai donné.
Le premier exemple est plus cher que l'arithmétique à virgule flottante est plus cher que l'arithmétique des nombres entiers.
(3) Flotteurs peut certainement déborder et les conséquences dépendent la mise en œuvre.
Comme Arjit a souligné, vous pouvez éviter un débordement en vérifiant la valeur de v1 avant d'effectuer le calcul. Si v1 pourrait être négatif vous devez également vérifier la version négative, et peut-être ce qui suit peut-être mieux ...
if ((LONG_LONG_MAX / 1000000) > V1)
{
...
}
Si vous êtes vraiment contre la limite que vous pourriez vous donner un peu plus de marge en déclarant les variables à unsigned
.
Plus tard - à modifier erreur correcte a par Arjit
.Autres conseils
Tout d'abord
- si cela INT ou calcul à long DonT impliquent flotteur à elle. Parce que votre résultat dans la première partie aurait beaucoup de valeurs différentes qui sont à peu près égales.
Parce que (float) v1 / v2 = ab.cdef. // où CDEF peut varier.
Votre deuxième mise en œuvre peut également faire déborder si v1 = 2 ^ 15 et v2 = 1
donc si vous êtes à la recherche de débordement et de la sécurité, vous devriez toujours vérifier
comme 2 ^ 18/1000000 constante qui est dans ce cas
if(2^18/Constant > v1)
result = (1000000 * (v1 / v2) + v1 % v2);
Ce serait une preuve de hack.
Hope this helps