Question

Je suis curieux de connaître ces langues (Java, C ...) qui ne tiennent pas la définition mathématique de fonctionnement du module.

Quel est le point de retour des valeurs négatives dans une opération de module (qui, par définition, devrait AllWays retourner un nombre positif)?

Était-ce utile?

La solution

Je doute que l'opérateur reste a été délibérément conçu pour avoir cette sémantique, que je suis d'accord ne sont pas très utiles. (Voulez-vous jamais écrire un programme de calendrier qui montre la semaine du dimanche, Anti-samedi, Anti-vendredi, ..., Anti-lundi pour les dates avant l'époque?)

Au contraire, les restes négatifs sont un effet secondaire de la manière dont la division entière est définie.

A rem B := A - (A div B) * B

Si A div B est défini comme trunc(A/B), vous obtenez l'opérateur % de C. Si A div B est défini comme floor(A/B), vous obtenez l'opérateur % Python. D'autres définitions sont possibles.

Alors, la vraie question est:

Pourquoi C ++, Java, C #, etc. division entière tronquer utilisation?

Parce que c'est la façon que C fait.

Pourquoi utilise-t-C division tronquer?

A l'origine, C n'a pas précisé comment / doit gérer les nombres négatifs. Il a laissé au matériel.

Dans la pratique, chaque mise en œuvre importante division C utilisé tronquer, donc en 1999 cette sémantique ont été officiellement fait une partie de la norme C.

Pourquoi la division utilisation du matériel tronquer?

Parce qu'il est plus facile (= moins cher) à mettre en œuvre en termes de division non signée. Vous venez de calculer abs(A) div abs(B) et retourner le signe si (A < 0) xor (B < 0).

Floored division a l'étape supplémentaire consistant à soustraire 1 du quotient si le reste est différent de zéro.

Autres conseils

En Java au moins, ce n'est pas un opérateur de module - c'est un opérateur reste .

Je crois que la raison étant choisie de cette façon est de faire ce travail de relation (des JLS):

Le calcul de reste pour des opérandes qui sont des nombres entiers après promotion numérique binaire (§5.6.2) produit une valeur de résultat de telle sorte que (a / b) * b + (a% b) est égal à un. Cette identité est valable même dans le cas particulier où le dividende est le nombre entier négatif de plus grande amplitude possible pour le type et le diviseur est -1 (le reste est égal à 0). Il résulte de cette règle que le résultat de l'opération reste peut être négatif que si le dividende est négatif, et peut être positif que si le dividende est positif; En outre, l'ampleur du résultat est toujours inférieure à la grandeur du diviseur.

Cette relation d'égalité semble être une chose raisonnable à utiliser dans le cadre de la définition. Si vous prenez la division tronquant vers zéro pour être un donné, que les feuilles vous avec un reste négatif.

De Wikipédia (je souligne):

Etant donné deux nombres positifs, un (dividende) et n (le diviseur), un modulo n (abrégé en tant que mod n) peut être considéré comme le reste, sur la division de a par n. Par exemple, l'expression "5 mod 4" pour évaluer pour une raison 5 divisé par 4 feuilles un reste de 1, tandis que « 9 mod 3" évaluerait à 0 parce que la division de 9 par 3 feuilles un reste de 0; il n'y a rien à soustraire de 9 après avoir multiplié 3 fois 3. (Remarquez que faire la division avec une calculatrice ne sera pas vous montrer le résultat visé ici par cette opération, le quotient sera exprimée en décimal.) Lorsque l'un ou n est négatif, ce casse définition naïve vers le bas et les langages de programmation diffèrent la façon dont ces valeurs sont définies. Bien que généralement réalisée avec un et n deux entiers étant, de nombreux systèmes informatiques permettent d'autres types de opérandes numériques. La gamme des nombres modulo un entier de n est 0 pour n - 1 (mod n 1 est toujours égal à 0; n 0 mod est défini, éventuellement entraînant une erreur « division par zéro » dans la programmation informatique langues) Voir l'arithmétique modulaire pour une convention ancienne et connexes appliquée en théorie des nombres.

La plupart d'entre eux ne sont pas définis pour retourner un module. Ce qu'ils sont définis au retour est un reste, pour lequel des valeurs positives et négatives sont également raisonnables.

En C ou C ++, il est assez raisonnable de dire qu'il devrait produire quel que soit le matériel sous-jacent produit. Cette excuse / raison ne fonctionne pas presque aussi bien pour Java bien.

A noter également que dans C89 / 90 et C ++ 98/03, le reste peut être soit positive ou négative, à condition que les résultats de reste et de division ont travaillé ensemble ((a/b)*b+a%b == a). Dans C99 et C ++ 11, les règles avaient été renforcées de sorte que la division doit tronquer vers zéro, et s'il y a un reste, il doit être négatif.

Une raison pragmatique pour retourner une valeur négative pour le module serait que le module matériel de mise en œuvre de l'instruction fait.

normes congé que mal définis, de sorte que les compilateurs peuvent faire tout ce qui est plus simple pour eux.

Dans aucune des normes C ou Java est % appelé un opérateur de module -. Au contraire, elle renvoie le reste

Il est défini retourner des nombres négatifs pour les dividendes négatifs de sorte que la relation (a/b)*b + a%b == a tient, aussi longtemps que a / b est représentable. Étant donné que l'opérateur de division est définie tronquer vers zéro, ce le signe limite du reste.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top