web-dev-qa-db-fra.com

Cast pour int vs sol

Y a-t-il une différence entre ceux-ci:

float foo1 = (int)(bar / 3.0);
float foo2 = floor(bar / 3.0);

Si je comprends bien les deux cas ont le même résultat. Y a-t-il une différence dans le code compilé?

107
OgreSwamp

Casting à un int tronquera vers zéro. floor() tronquera vers l'infini négatif. Cela vous donnera des valeurs différentes si bar était négatif.

170
James Curran

Comme il a été dit précédemment, ils sont identiques pour les nombres positifs, mais ils diffèrent pour les nombres négatifs. La règle est que int arrondit vers 0, alors que floor arrondit vers l'infini négatif.

floor(4.5) = (int)4.5 = 4
floor(-4.5) = -5 
(int)(-4.5) = -4

Cela étant dit, il existe également une différence de temps d'exécution. Sur mon système, j'ai déterminé que la diffusion est au moins 3 fois plus rapide que le plancher.

J'ai un code qui nécessite l'opération au sol d'une plage de valeurs limitée, y compris des nombres négatifs. Et il doit être très efficace, nous utilisons donc la fonction suivante:

int int_floor(double x) 
{ 
    return (int)(x+100000) - 100000; 
}

Bien sûr, cela échouera pour les très grandes valeurs de x (vous rencontrerez des problèmes de dépassement de capacité) et pour les valeurs négatives inférieures à -100000, etc. pour notre application. Prenez-le avec un grain de sel, testez-le sur votre système, etc., mais cela vaut la peine d'envisager un IMHO.

24
brice rebsamen

SO 101, ne changez pas votre question une fois que des personnes ont répondu à votre question, écrivez plutôt une nouvelle question.

Pourquoi pensez-vous qu'ils auront le même résultat?

float foo = (int)(bar / 3.0) //will create an integer then assign it to a float

float foo = fabs(bar / 3.0 ) //will do the absolute value of a float division

bar = 1.0

foo1 = 0;
foo2 = 0.33333...
9
Anders

EDIT: Parce que la question peut avoir été modifiée en raison de la confusion entre fabs() et floor().

Étant donné les lignes d’exemple de la question initiale:

1.  float foo = (int)(bar / 3.0);

2.  float foo = fabs(bar / 3.0);

La différence est que si bar est négatif, le résultat sera négatif avec le premier mais positif avec le second. Le premier sera tronqué en un entier et le second renverra la valeur décimale complète, y compris la partie décimale.

4
Amardeep AC9MF

Oui. fabs renvoie la valeur absolue de son argument, et la conversion en int provoque la troncature de la division (jusqu'au int le plus proche), ainsi les résultats seront presque toujours différents.

3
warrenm

Il y a deux différences principales:

  1. Comme d'autres l'ont souligné, la conversion en un entier tronquera vers zéro, alors que floor() tronquera toujours vers l'infini négatif; C'est un comportement différent pour un opérande négatif.

  2. Personne ne semble (encore) avoir signalé une autre différence - si votre argument est supérieur ou égal à MAX_INT+1 (ou moins que -MAX_INT-1) puis transtyper en int entraînera la suppression des bits les plus importants (C, probablement) ou un comportement indéfini (C++ et éventuellement C). Par exemple, si votre int est de 32 bits, vous ne disposez que d’un bit de signe et de 31 bits de données. Donc, utiliser ceci avec un double de grande taille va produire des résultats inattendus.

2
abligh

(int) x Est une requête pour conserver la partie entière de x (il n'y a pas d'arrondi ici)

fabs(x) = | x | de sorte que c'est >= 0;

Ex: (int) -3.5 Renvoie -3; fabs(-3.5) renvoie 3.5;

En général, fabs (x) >= x pour tout x;

x >= (int) x si x >= 0

x < (int) x si x < 0

0
Paul Hoang