Dans le code créé par Apple, il y a cette ligne:
CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )
Existe-t-il une raison pour exprimer 1,000,000,000
sous la forme 1000*1000*1000
?
Pourquoi pas 1000^3
d'ailleurs?
Une des raisons pour déclarer des constantes de manière multiplicative est d'améliorer la lisibilité, sans affecter les performances d'exécution. En outre, pour indiquer que l'auteur pensait de manière multiplicative au nombre.
Considère ceci:
double memoryBytes = 1024 * 1024 * 1024;
C'est clairement mieux que:
double memoryBytes = 1073741824;
comme ce dernier ne ressemble pas, à première vue, au troisième pouvoir de 1024.
Comme Amin Negm-Awad l'a mentionné, l'opérateur ^
est le binaire XOR
. De nombreuses langues n'ont pas d'opérateur d'exponentiation intégré à la compilation, d'où la multiplication.
Pourquoi pas
1000^3
?
Le résultat de 1000^3
est 1003. ^
est l'opérateur bit-XOR.
Même s'il ne traite pas du Q lui-même, j'ajoute une clarification. x^y
fait pas évalue toujours à x+y
comme dans l'exemple de l'interrogateur. Vous devez xor chaque bit. Dans le cas de l'exemple:
1111101000₂ (1000₁₀)
0000000011₂ (3₁₀)
1111101011₂ (1003₁₀)
Mais
1111101001₂ (1001₁₀)
0000000011₂ (3₁₀)
1111101010₂ (1002₁₀)
Il y a des raisons pas d'utiliser 1000 * 1000 * 1000
.
Avec int
16 bits, 1000 * 1000
déborde. Donc, utiliser 1000 * 1000 * 1000
réduit la portabilité.
Avec int
32 bits, les débordements suivants.
long long Duration = 1000 * 1000 * 1000 * 1000; // overflow
long long Duration = 1000000000000; // no overflow, hard to read
Suggérez que la valeur de prospect corresponde au type de destination pour la lisibilité, la portabilité et la correction.
double Duration = 1000.0 * 1000 * 1000;
long long Duration = 1000LL * 1000 * 1000 * 1000;
Vous pouvez également utiliser simplement la notation e
pour les valeurs qui sont exactement représentables en tant que double
. Bien entendu, cela nous amène à savoir si double
peut représenter exactement la valeur du nombre entier, ce qui est préoccupant pour les valeurs supérieures à 1e9. (Voir DBL_EPSILON
et DBL_Dig
).
long Duration = 1000000000;
// vs.
long Duration = 1e9;
Pour la lisibilité.
Le fait de placer des virgules et des espaces entre les zéros (1 000 000 000
ou 1,000,000,000
) produirait une erreur de syntaxe. Le fait que 1000000000
soit inscrit dans le code empêche de savoir exactement combien de zéros se trouvent à cet endroit.
1000*1000*1000
indique clairement qu'il est 10 ^ 9, car nos yeux peuvent traiter les morceaux plus facilement. En outre, il n'y a pas de coût d'exécution, car le compilateur le remplacera par la constante 1000000000
.
Pour la lisibilité. Pour comparaison, Java prend en charge _
en chiffres pour améliorer la lisibilité (proposé pour la première fois par Stephen Colebourne en réponse à la PROPOSITION de Derek Foster: Binary Literals pour Project Coin/JSR 334). On écrirait 1_000_000_000
ici.
En gros, chronologiquement, du support le plus ancien au plus récent:
"(1)1111 1111"
( apparemment pas pour les valeurs décimales, uniquement pour les chaînes de bits représentant des valeurs binaires, quartales, octales ou hexadécimales )1$000$000
1_000_000_000
1'000'000'000
C'est une fonctionnalité relativement nouvelle pour les langues à se rendre compte qu'elles devraient prendre en charge (et puis il y a Perl). Comme dans l'excellente réponse de chux @, 1000*1000...
est une solution partielle mais ouvre le programmeur aux bugs dus au débordement de la multiplication, même si le résultat final est un type volumineux.
Pourrait être plus simple à lire et obtenir des associations avec le formulaire 1,000,000,000
.
D'un point de vue technique, je suppose qu'il n'y a pas de différence entre le nombre direct et la multiplication. Le compilateur le générera quand même comme un nombre constant de milliards.
Si vous parlez d’objectif-c, alors 1000^3
ne fonctionnera pas car il n’existe pas de telle syntaxe pour pow (c’est xor). À la place, la fonction pow()
peut être utilisée. Mais dans ce cas, ce ne sera pas optimal, ce sera un appel de fonction d'exécution et non une constante générée par le compilateur.
Pour illustrer les raisons, considérons le programme de test suivant:
$ cat comma-expr.c && gcc -o comma-expr comma-expr.c && ./comma-expr
#include <stdio.h>
#define BILLION1 (1,000,000,000)
#define BILLION2 (1000^3)
int main()
{
printf("%d, %d\n", BILLION1, BILLION2);
}
0, 1003
$
Une autre façon d'obtenir un effet similaire en C pour les nombres décimaux consiste à utiliser la notation littérale en virgule flottante - tant qu'un double peut représenter le nombre que vous voulez sans perte de précision.
Le double 64 bits IEEE 754 peut représenter un entier non négatif <= 2 ^ 53 sans problème. Typiquement, les doubles longs (80 ou 128 bits) peuvent aller encore plus loin que cela. Les conversions étant effectuées au moment de la compilation, il n’ya pas de temps d’exécution supplémentaire et vous aurez probablement des avertissements en cas de perte de précision inattendue et si vous avez un bon compilateur.
long lots_of_secs = 1e9;