Perché l’operatore modulo non funziona per double in c #?

Considera questo:

double x,y; x =120.0; y = 0.05; double z= x % y; 

Ho provato questo e mi aspettavo che il risultato fosse 0, ma è uscito 0.04933333.

Però,

 x =120.0; y = 0.5; double z= x % y; 

ha effettivamente dato il risultato corretto di 0.

Cosa sta succedendo qui?

Ho provato Math.IEEERemainder(double, double) ma non restituisce neanche 0. Che cosa sta succedendo qui?

Inoltre, per inciso, qual è il modo più appropriato per trovare il resto in C #?

A causa del suo formato di archiviazione, double s non può memorizzare tutti i valori esattamente come è stato inserito o visualizzato. La rappresentazione umana dei numeri è solitamente in formato decimale, mentre i double sono basati sul sistema duale.

In un double , 120 viene memorizzato precisamente perché è un valore intero. Ma 0.05 non lo è. Il doppio è approssimato al numero più vicino a 0.05 che può rappresentare. 0.5 è una potenza di 2 ( 1/2 ), quindi può essere memorizzata con precisione e non si ottiene un errore di arrotondamento.

Per avere tutti i numeri esattamente nello stesso modo in cui inserisci / visualizzi nel sistema decimale, usa invece i decimal .

 decimal x, y; x = 120.0M; y = 0.05M; decimal z = x % y; // z is 0 

Potresti fare qualcosa come:

 double a, b, r; a = 120; b = .05; r = a - Math.floor(a / b) * b; 

Questo dovrebbe aiutare;)

Credo che se avessi provato lo stesso con i decimal avrebbe funzionato correttamente.

Il modulo dovrebbe essere usato solo con numero intero. Il resto proviene da una divisione euclidea. Con il doppio, puoi avere risultati imprevisti.

Vedi questo articolo

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems può aiutarti a capire perché ottieni questi risultati “strani”. C’è una precisione particolare che i numeri in virgola mobile possono avere. Basta provare queste domande e dare un’occhiata ai risultati:

0,5 nella base 2

0,05 nella base 2