2010-06-01 17 views
38

Sto creando un calcolatore RPN per un progetto scolastico. Sto avendo problemi con l'operatore modulo. Dato che stiamo usando il doppio tipo di dati, il modulo non funzionerà su numeri in virgola mobile. Ad esempio, 0,5% 0,3 dovrebbe restituire 0,2 ma sto ottenendo una divisione per eccezione zero.Come utilizzare il modulo per float/double?

L'istruzione dice di usare fmod(). Ho cercato ovunque fmod(), incluso javadocs ma non riesco a trovarlo. Sto iniziando a pensare che sia un metodo che dovrò creare?

modifica: hmm, strano. Ho appena ricollegato quei numeri e sembra che stia funzionando bene ... ma per ogni evenienza. Devo fare attenzione a usare l'operatore mod in Java quando utilizzo i tipi floating? So che qualcosa del genere non può essere fatto in C++ (credo).

risposta

59

Probabilmente si è verificato un errore durante la prima esecuzione.

valutazione 0.5 % 0.3 restituisce '0,2' (A doppio) come previsto.

Mindprod ha un good overview of how modulus works in Java (guardare verso destra per il modulo a virgola mobile).

+1

ma '1.0% 0.1' restituisce ...' 0.09999999999999995', come risultato di un errore di arrotondamento. Qualche idea su come correggere questo (presumibilmente con valori epsilon?) Gli errori di arrotondamento – Groostav

+1

si verificheranno sempre nei calcoli in virgola mobile. Prendere il valore dato o arrotondarlo al valore più vicino necessario. – Anarchofascist

+0

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

5

Ho pensato che l'operatore modulo normale avrebbe funzionato per questo in Java, ma non può essere difficile da codificare. Basta dividere il numeratore per il denominatore e prendere la parte intera del risultato. Moltiplicare quello per il denominatore e sottrarre il risultato dal numeratore.

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

fmod è la funzione standard C per la gestione del modulo a virgola mobile; Immagino che la tua fonte stia dicendo che Java gestisce il modulo a virgola mobile come la funzione fmod di C. In Java è possibile utilizzare l'operatore % sul raddoppia la stessa su interi:

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

differenza di C, Java permette usando l'% sia interi e virgola mobile e (a differenza C89 e C++) è ben definito per tutti gli ingressi (inclusi i negativi):

da JLS §15.17.3:

Il risultato di una virgola mobile funzionamento restante è determinata dalle regole dell'aritmetica IEEE:

  • Se uno degli operandi è NaN, il risultato è NaN.
  • Se il risultato non è NaN, il segno del risultato è uguale al segno di il dividendo.
  • Se il dividendo è un infinito o il divisore è uno zero o entrambi, il risultato è NaN.
  • Se il dividendo è finito e il divisore è infinito, il risultato corrisponde al dividendo.
  • Se il dividendo è uno zero e il divisore è finito, il risultato corrisponde al dividendo.
  • Negli altri casi, in cui né un infinito, né uno zero, né NaN è coinvolto, la virgola mobile resto r della divisione di un dividendo n per un divisore D viene definito dal matematico rapporto r = n- (d · q) dove q è un numero intero che è negativo solo se n/d è negativo e positivo solo se n/d è positivo e la cui grandezza è il più grande possibile senza superare la magnitudine del quoziente matematico vero di nd d.

Quindi per il vostro esempio, 0,5/0,3 = 1,6 .... q ha lo stesso segno (positivo) come 0,5 (il dividendo) e la magnitudine è 1 (intero con grandezza massima non superiore a 1,6 ...), e r = 0,5 - (0,3 * 1) = 0,2

+2

L'ultimo punto elenco è un muro di testo. Sarebbe più chiaro dire che con un esempio: '0,5% 0,3 = 0,2' e' (-0,5)% 0,3 = -0,2' – GameDeveloper

Problemi correlati