93 votes

Pourquoi la division de module (`%`) ne fonctionne-t-elle qu'avec des entiers?

J'ai récemment rencontré un problème qui pourrait être facilement résolu en utilisant le module de la division, mais l'entrée était un float:

Étant donné une fonction qui se répète (ex: sin), et la fonction de l'ordinateur que ne peut la calculer lorsque la plage est l'intérieur d'un segment de gamme (ex: -pi à pi), faire une fonction qui permet de gérer n'importe quelle entrée.

Le "évident" la solution est quelque chose comme:

#include <cmath>
float sin(float x){
    return limited_sin((x + M_PI) % (2 *M_PI) - M_PI);
}

Pourquoi ne pas ce travail? J'obtiens cette erreur:

error: invalid operands of types double and double to binary operator %

Il est intéressant de noter, c'est en Python:

def sin(x):
    return limited_sin((x + math.pi) % (2 * math.pi) - math.pi)

85voto

AndreyT Points 139512

Parce que la normale notion mathématique de "reste" n'est applicable qu'à la division entière. c'est à dire la division qui est nécessaire pour générer le quotient entier.

Afin d'étendre la notion de "reste" des nombres réels, vous devez introduire un nouveau type d ' "hybride" de l'opération, qui permettrait de générer entier , le quotient de réel opérandes. De base du langage C ne prend pas en charge l'opération, mais il est fourni en standard library fmod fonction, ainsi que d' remainder fonction en C99. (Notez que ces fonctions ne sont pas les mêmes et ont quelques particularités. En particulier, ils ne suivent pas les règles d'arrondi de la division entière.)

62voto

Doug Stephen Points 3913

Vous êtes à la recherche pour fmod().

Je suppose que pour plus de répondre spécifiquement à votre question, dans les anciennes langues de l' % de l'opérateur a été défini comme un entier modulaire de la division et de nouvelles langues, ils ont décidé d'élargir la définition de l'opérateur.

EDIT: Si je devais miser deviner pourquoi, je dirais que c'est parce que l'idée de l'arithmétique modulaire est originaire de la théorie et de la traite spécifiquement avec des entiers.

18voto

Jerry Coffin Points 237758

Je ne peux pas vraiment dire avec certitude , mais je suppose que c'est principalement historique. Quelques premiers compilateurs C ne supportaient pas du tout les virgules flottantes. Il a été ajouté plus tard, et même alors pas aussi complètement - la plupart du temps, le type de données a été ajouté et les opérations les plus primitives prises en charge dans le langage, mais tout le reste a été laissé à la bibliothèque standard.

12voto

Mark Elliot Points 31871

L'opérateur modulo % en C et C ++ est défini pour deux entiers. Cependant, une fonction fmod() est disponible pour une utilisation avec des doublons.

7voto

Yu Hao Points 40603

Les contraintes sont dans les normes:

C11(ISO/IEC 9899:201x) §6.5.5 Multiplicatif opérateurs

Chacun des opérandes ont arithmétique type. Les opérandes de l'opérateur % est ont type entier.

C++11(ISO/IEC 14882:2011) §5.6 Multiplicatif opérateurs

Les opérandes d' * et / doivent avoir de l'arithmétique ou de type énumération; les opérandes d' % ont intégré ou de l'énumération type. L'habitude de l'arithmétique conversions sont effectuées sur les opérandes et de déterminer le type du résultat.

La solution est d'utiliser fmod, ce qui est exactement pourquoi les opérandes d' % sont limités à type entier, en premier lieu, selon C99 Justification §6.5.5 Multiplicatif opérateurs:

Le C89 Commission a rejeté l'extension de la % à l'opérateur de travailler sur les types flottants qu'un tel usage entraînerait un chevauchement des installations fournies par fmod

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