2010-06-01 8 views
38

Je crée une calculatrice RPN pour un projet d'école. J'ai des problèmes avec l'opérateur de module. Puisque nous utilisons le type de données double, le module ne fonctionnera pas sur les nombres à virgule flottante. Par exemple, 0.5% 0.3 devrait renvoyer 0.2 mais j'obtiens une division par zéro exception.Comment utiliser le module pour float/double?

L'instruction indique d'utiliser fmod(). J'ai cherché partout fmod(), y compris javadocs mais je ne le trouve pas. Je commence à penser que c'est une méthode que je vais devoir créer?

modifier: hmm, strange. Je viens de brancher à nouveau ces chiffres et ça semble fonctionner correctement ... mais juste au cas où. Ai-je besoin de faire attention en utilisant l'opérateur mod en Java lorsque j'utilise des types flottants? Je sais que quelque chose comme ça ne peut pas être fait en C++ (je pense).

Répondre

59

Vous avez probablement eu une faute de frappe lors de la première exécution.

évaluation 0.5 % 0.3 renvoie '0.2' (A double) comme prévu.

Mindprod a un good overview of how modulus works en Java (regardez à la fin pour le module en virgule flottante).

+1

mais '1.0% 0.1' renvoie ...' 0.09999999999999995', comme le résultat d'une erreur d'arrondi. Une idée de comment corriger cela (vraisemblablement avec des valeurs epsilon?) – Groostav

+1

erreurs d'arrondi arrivera toujours dans les calculs à virgule flottante. Soit prendre la valeur telle qu'elle est donnée, soit l'arrondir à la valeur nécessaire la plus proche. – Anarchofascist

+0

'String.format ("% .8f ", 1.0% 0.1)' renvoie '0.10000000' – Anarchofascist

5

Je pensais que l'opérateur de module régulier fonctionnerait pour cela en Java, mais il ne peut pas être difficile à coder. Juste diviser le numérateur par le dénominateur, et prendre la partie entière du résultat. Multipliez cela par le dénominateur et soustrayez le résultat du numérateur.

x = n/d 
xint = Integer portion of x 
result = n - d * xint 
2

fmod est la fonction C standard pour la gestion du module en virgule flottante; J'imagine que votre source disait que Java gère le module à virgule flottante comme la fonction fmod de C. En Java, vous pouvez utiliser l'opérateur % sur double le même que sur les entiers:

int x = 5 % 3; // x = 2 
double y = .5 % .3; // y = .2 
37

Contrairement à C, Java permet d'utiliser le% pour les nombres entiers et en virgule flottante et (contrairement à C89 et C++), il est bien défini pour toutes les entrées (y compris les négatifs):

de JLS §15.17.3:

Le résultat d'une virgule flottante de reste est déterminée par les règles de l'arithmétique IEEE:

  • Si l'un des opérandes est NaN, le résultat est NaN.
  • Si le résultat n'est pas NaN, le signe du résultat est égal au signe de le dividende.
  • Si le dividende est un infini, ou si le diviseur est un zéro, ou les deux, le résultat est NaN. Si le dividende est fini et le diviseur est une infinité, le résultat est égal au dividende.
  • Si le dividende est un zéro et que le diviseur est fini, le résultat est égal au dividende.
  • Dans les autres cas, où ni une infinité, ni un zéro, ni NaN est impliqué, la virgule flottante reste r de la division d'un dividende n par un diviseur d est défini par la relation mathématique r = n- (d · q) où q est un entier négatif seulement si n/d est négatif et positif seulement si n/d est positif, et dont l'amplitude est sans dépasser l'amplitude du vrai quotient mathématique de n et d.

Donc pour votre exemple, 0,5/0,3 = 1,6 .... q a le même signe (positif) que 0.5 (le dividende), et la grandeur est 1 (entier avec la grandeur la plus grande n'excédant pas la magnitude de 1.6 ...), et r = 0.5 - (0.3 * 1) = 0.2

+2

Le dernier point est un mur de texte. Il serait plus clair de dire que par un exemple: '0.5% 0.3 = 0.2' et' (-0.5)% 0.3 = -0.2' – GameDeveloper

Questions connexes