2010-06-01 13 views
38

Estoy creando una calculadora RPN para un proyecto escolar. Estoy teniendo problemas con el operador de módulo. Dado que estamos utilizando el tipo de datos doble, el módulo no funcionará en números de coma flotante. Por ejemplo, 0.5% 0.3 debería devolver 0.2 pero estoy obteniendo una excepción de división por cero.¿Cómo se usa el módulo para flotación/doble?

La instrucción dice que use fmod(). He buscado fmod() en todos lados, incluidos javadocs, pero no puedo encontrarlo. Estoy empezando a pensar que es un método que voy a tener que crear?

editar: hmm, extraño. Acabo de enchufar esos números nuevamente y parece estar funcionando bien ... pero por las dudas. ¿Debo tener cuidado con el operador de mod en Java cuando uso tipos flotantes? Sé que algo así no se puede hacer en C++ (creo).

Respuesta

59

Probablemente tuvo un error tipográfico cuando lo usó por primera vez.

evaluando 0.5 % 0.3 devuelve '0.2' (A double) como se esperaba.

Mindprod tiene un good overview of how modulus works en Java (mira al final para el módulo de coma flotante).

+1

pero '1.0% 0.1' devuelve ...' 0.09999999999999995', como resultado de un error de redondeo. ¿Alguna idea de cómo corregir esto (presumiblemente con valores épsilon?) – Groostav

+1

los errores de redondeo siempre ocurrirán en los cálculos de punto flotante. O tome el valor tal como está dado, o redondee al valor necesario más cercano. – Anarchofascist

+0

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

5

Pensé que el operador de módulo regular funcionaría para esto en Java, pero no puede ser difícil de codificar. Simplemente divida el numerador por el denominador y tome la parte entera del resultado. Multiplique eso por el denominador, y reste el resultado del numerador.

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

fmod es la función C estándar para manejar el módulo de coma flotante; Me imagino que su fuente decía que Java maneja el módulo de coma flotante de la misma manera que la función de C fmod. En Java se puede utilizar el operador % en dobles el mismo que en números enteros:

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

A diferencia de C, Java permite utilizar el% para los dos números enteros y de coma flotante y (a diferencia de C89 y C++) es bien definido para todas las entradas (incluyendo negativos):

Desde JLS §15.17.3:

El resultado de una de coma flotante operación resto se determina por las reglas de la aritmética IEEE:

  • Si cualquier operando es NaN, el resultado es NaN.
  • Si el resultado no es NaN, el signo del resultado es igual al signo de del dividendo.
  • Si el dividendo es infinito, o el divisor es cero, o ambos, el resultado es NaN.
  • Si el dividendo es finito y el divisor es infinito, el resultado es igual al dividendo.
  • Si el dividendo es cero y el divisor es finito, el resultado es igual al dividendo.
  • En los casos restantes, donde ni una infinidad, ni un cero, ni NaN está involucrado, el de punto flotante resto r de la división de un dividendo n por un divisor D se define por la relación matemática r = n- (d · q) donde q es un número entero que es negativo sólo si n/d es negativo y positivo sólo si n/d es positivo, y cuya magnitud es lo más grande posible sin exceder la magnitud del verdadero cociente matemático de nyd.

Para su ejemplo, 0.5/0.3 = 1.6 .... q tiene el mismo signo (positivo) que 0.5 (el dividendo), y la magnitud es 1 (número entero con una magnitud mayor que no excede la magnitud de 1.6 ...), yr = 0.5 - (0.3 * 1) = 0.2

+2

El último punto es un muro de texto. Sería más claro decir que con un ejemplo: '0.5% 0.3 = 0.2' y' (-0.5)% 0.3 = -0.2' – GameDeveloper

Cuestiones relacionadas