2012-02-04 6 views
138

J'ai un programme en C++ (compilé en utilisant g ++). J'essaie d'appliquer deux doubles comme opérandes à la fonction de module, mais je reçois l'erreur suivante:Vous ne pouvez pas utiliser le module sur les doubles?

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

Voici le code:

int main() { 
    double x = 6.3; 
    double y = 2; 
    double z = x % y; 
} 
+9

Comme il a été noté, fmod() fournit la fonction nécessaire. Comme cela n'a pas encore été noté, il est important de réaliser que les erreurs d'arrondi dans le second opérande de 'fmod' peuvent provoquer des comportements inattendus. Par exemple, 'fmod (1, 0.1);' devrait mathématiquement être zéro, mais sera en fait proche de 0.1. L'ampleur de l'erreur augmente avec l'ampleur du quotient. Par exemple, 'fmod (9E14, 0.1);' évalue à environ 0.05, ce qui est purement mathématique. – supercat

+1

@supercat plus de détails serait génial. Je pense avoir une idée de ce qui se passe dans les coulisses pour que ce que vous dites soit vrai, mais ce serait bien de voir les raisons pour lesquelles ce que vous dites est vrai; serait intéressant de voir comment cela fonctionne dans les coulisses (je pense que je comprends, mais pourrait très bien se tromper). – RastaJedi

+2

Les valeurs à virgule flottante représentent des multiples entiers exacts ou des fractions de puissances de deux. Par exemple, le littéral entier 0.1 est exactement 3602879701896397/36028797018963968 (la dernière valeur est une puissance de deux). 'fmod (x, 0.1)' divisera x par cette fraction précise et prendra le reste, plutôt que de diviser par la valeur numérique "un dixième". – supercat

Répondre

214

L'opérateur % est pour les entiers. Vous cherchez le fmod() function.

#include <cmath> 

int main() 
{ 
    double x = 6.3; 
    double y = 2.0; 
    double z = std::fmod(x,y); 

} 
+0

Je suis en programmation en C++ pour Qt et fmod a un bug là. Le résultat de fmod (angle, 360) peut être 360 ​​(WAT?!) – Paul

+1

@Paul: Ce n'est probablement pas un bug. Si 'angle' est, disons, '359.9999999', alors' angle' et 'fmod (angle, 360)' sont susceptibles d'être affichés comme '360'. (Ajoutez plus de 9 si nécessaire.) Essayez d'imprimer les valeurs avec, disons, 50 chiffres de précision. –

33

fmod(x, y) est la fonction que vous utilisez.

2

Utilisez fmod() à partir de <cmath>. Si vous ne voulez pas inclure le fichier d'en-tête C (note: U ne peut pas être float ou double):

template<typename T, typename U> 
constexpr T dmod (T x, U mod) 
{ 
    return !mod ? x : static_cast<long long>(x) % mod + x - static_cast<long long>(x); 
} 

//Usage: 
double z = dmod<double, unsigned int>(14.3, 4); 
double z = dmod<long, short>(14, 4); 
//This also works: 
double z = dmod(14, 4); 
double z = dmod(14, 0); 
double z = dmod(myFirstVariable, someOtherVariable); 
+0

Pourquoi ne voudriez-vous pas inclure le fichier d'en-tête C? C'est ce qu'il y a là-bas. –

Questions connexes