143 votes

Pourquoi écrire 1 000 000 000 comme 1000*1000*1000 en C ?

Dans le code créé par Apple, il y a cette ligne :

CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )

Y a-t-il une raison d'exprimer 1,000,000,000 comme 1000*1000*1000 ?

Pourquoi pas 1000^3 d'ailleurs ?

46 votes

Clarté et lisibilité du code. Vous ne pouvez pas utiliser , ou ' comme séparateurs en C, donc la meilleure solution est de calculer la valeur d'une multiplication. ^ est un opérateur non apparenté en C - OU exclusif.

54 votes

Il est surtout utilisé pour des durées telles que : 2*60*60 il est facile de remarquer qu'il s'agit de 2 heures .

53 votes

D'une part, je pense que 1 000 000 000 n'est pas une syntaxe valable.

203voto

Piotr Falkowski Points 1582

L'une des raisons de déclarer les constantes de manière multiplicative est d'améliorer la lisibilité, sans affecter les performances d'exécution. Cela permet également d'indiquer que l'auteur a pensé au nombre d'une manière multiplicative.

Considérez ceci :

double memoryBytes = 1024 * 1024 * 1024;

C'est nettement mieux que :

double memoryBytes = 1073741824;

car ce dernier ne semble pas, à première vue, être la troisième puissance de 1024.

Comme l'a mentionné Amin Negm-Awad, la ^ est l'opérateur binaire XOR . De nombreux langages ne disposent pas d'un opérateur d'exponentiation intégré à la compilation, d'où la multiplication.

13 votes

Et dans les langages qui disposent d'un opérateur d'exponentiation, celui-ci n'est pas nécessairement "^". En Fortran, par exemple, c'est "**".

4 votes

Vous devriez également inclure un lien pointant vers la mise en garde importante, donnée dans la réponse ci-dessous, de @chux : stackoverflow.com/a/40637622/1841533 (d'autant plus que le PO a étiqueté "c", qui est très sensible à ce problème de "l'opération du côté droit semble avoir tous les termes limités à un type plus petit, et donc la multiplication peut déborder"). securecoding.cert.org/confluence/display/c/ peut aider à éviter ces problèmes dans le cas général ?

4 votes

Il convient également de noter que le calcul est effectué au moment de la compilation. La norme C exige que l'implémentation soit capable de calculer des expressions constantes au moment de la compilation pour diverses caractéristiques du langage et nous pouvons supposer sans risque que c'est le cas lorsqu'une expression constante est utilisée comme dans cet exemple.

74voto

chux Points 13185

Il y a des raisons pas à utiliser 1000 * 1000 * 1000 .

Avec 16 bits int , 1000 * 1000 déborde. Ainsi, l'utilisation de 1000 * 1000 * 1000 réduit la portabilité.

Avec 32-bit int la première ligne de code suivante déborde.

long long Duration = 1000 * 1000 * 1000 * 1000;  // overflow
long long Duration = 1000000000000;  // no overflow, hard to read

Suggérer que la valeur du plomb corresponde au type de destination pour des raisons de lisibilité et de portabilité. y l'exactitude.

double Duration = 1000.0 * 1000 * 1000;
long long Duration = 1000LL * 1000 * 1000 * 1000;

On pourrait aussi utiliser simplement e pour les valeurs qui sont exactement représentables sous la forme d'un double . Bien entendu, cela conduit à savoir si double peut représenter exactement la valeur du nombre entier, ce qui pose problème pour les valeurs supérieures à 1e9 (voir DBL_EPSILON et DBL_DIG ).

long Duration = 1000000000;
// vs.
long Duration = 1e9;

5 votes

Remarque très importante ! securecoding.cert.org/confluence/display/c/ peut aider dans de nombreux cas ?

2 votes

A double peut représenter exactement tous les entiers jusqu'à 2^53 9e15.

3 votes

@EdgarBonet C'est vrai binaire64 peut représenter des nombres entiers jusqu'à environ 9e15. Mais C ne précise pas double l'utilisation de binary64, bien qu'il soit très couramment utilisé. Selon les spécifications du langage C, les valeurs jusqu'à 1e9 environ sont exactement représentables. Tout dépend si vous voulez coder selon les spécifications ou si vous vous fiez à la pratique courante.

73voto

Amin Negm-Awad Points 3340

Pourquoi pas 1000^3 ?

Le résultat de 1000^3 est de 1003. ^ est l'opérateur bit-XOR.

Même s'il ne s'agit pas de la question elle-même, j'apporte une précision. x^y fait pas sont toujours évalués à x+y comme dans l'exemple de l'auteur de la question. Il faut xer chaque bit. Dans le cas de l'exemple :

1111101000 (1000)
0000000011 (3)
1111101011 (1003)

Mais

1111101001 (1001)
0000000011 (3)
1111101010 (1002)

3 votes

Monsieur, je ne comprends pas bien comment 1003^3 est 1003. Google et Mac Calculator montrent que 1000^3 = 1,000,000,000. Pouvez-vous m'expliquer ?

59 votes

Les ^ signifie XOR en C/C++/Objective-C, etc. Dans les calculatrices, il signifie généralement x à la puissance y.

5 votes

Bah, les bits de 1000 et 3 ne se chevauchent pas. Cela ressemble à donc erronée.

51voto

Tamás Zahola Points 1352

Pour plus de lisibilité.

En plaçant des virgules et des espaces entre les zéros ( 1 000 000 000 o 1,000,000,000 ) produirait une erreur de syntaxe, et le fait d'avoir 1000000000 dans le code ne permet pas de voir exactement le nombre de zéros.

1000*1000*1000 permet de voir qu'il s'agit de 10^9, car nos yeux peuvent traiter les morceaux plus facilement. De plus, il n'y a pas de coût d'exécution, car le compilateur le remplacera par la constante 1000000000 .

5 votes

Pour information, il existe un concept de séparateurs de chiffres que j'ai appris à connaître récemment. Java l'a depuis un certain temps déjà, et C# 7.0 pourrait l'obtenir. J'aimerais que tous les langages disposent de cette fonctionnalité intéressante :)

1 votes

Selon le contexte, l'utilisation de 1,000,000,000 ne produirait pas d'erreur de syntaxe, elle signifierait simplement autre chose. Par exemple CMTimeMakeWithSeconds( newDurationSeconds, 1,000,000,000 )

2 votes

@JMS10 C# l'a déjà si vous installez la version preview de VS15, elle peut être écrite comme suit 1_000_000_000

27voto

djechlin Points 18051

Pour plus de lisibilité. À titre de comparaison, Java prend en charge _ en nombre pour améliorer la lisibilité (proposé pour la première fois par Stephen Colebourne en tant qu'outil de gestion de l'information). Réponse à la PROPOSITION de Derek Foster : Littéraux binaires pour Project Coin/JSR 334) . On pourrait écrire 1_000_000_000 ici.

Dans un ordre à peu près chronologique, du soutien le plus ancien au plus récent :

Il s'agit d'une fonctionnalité relativement nouvelle pour les langages qui réalisent qu'ils doivent la prendre en charge (et puis il y a Perl). Comme dans l'excellente réponse de chux@, 1000*1000... est une solution partielle, mais elle expose le programmeur à des bogues dus au débordement de la multiplication, même si le résultat final est un grand type.

0 votes

De nombreux langages de programmation modernes ont la même chose, par exemple Swift. Rien de nouveau.

0 votes

AFAIK, cela vient de Perl. PL/M utilisait $ dans le même but, par exemple : 0100$0010B

1 votes

Il est assez récente, cependant. La fonction Java a peut-être 5 ans. La plupart des autres langages supportant cette syntaxe sont assez récents - Swift lui-même n'a que quelques années. Python ajoute la prise en charge dans la version 3.6, qui n'a pas encore été publiée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X