avakar aveva quasi ragione - utilizzare modf, ma il dettaglio era spento.
modf restituisce la parte frazionaria, quindi il test dovrebbe essere che il risultato di modf è 0.0.
modf accetta due argomenti, il secondo dei quali dovrebbe essere un puntatore dello stesso tipo del primo argomento. Passare NULL o 0 causa un errore di segmentazione nel runtime g ++. Lo standard non specifica che passare 0 sia sicuro; potrebbe essere che capiti di lavorare sulla macchina di Avakar ma non farlo.
È inoltre possibile utilizzare fmod(a,b)
che calcola il modulo a
b
passando a 1.0. Anche questo dovrebbe dare la parte frazionaria.
#include<cmath>
#include<iostream>
int main()
{
double d1 = 555;
double d2 = 55.343;
double int_part1;
double int_part2;
using namespace std;
cout << boolalpha;
cout << d1 << " " << modf (d1, &int_part1) << endl;
cout << d1 << " " << (modf (d1, &int_part1) == 0.0) << endl;
cout << d2 << " " << modf (d2, &int_part2) << endl;
cout << d1 << " " << (modf (d2, &int_part2) == 0.0) << endl;
cout << d2 << " " << modf (d2, &int_part2) << endl;
cout << d1 << " " << (modf (d2, &int_part2) == 0.0) << endl;
cout << d1 << " " << fmod (d1, 1.0) << endl;
cout << d1 << " " << (fmod (d1, 1.0) == 0) << endl;
cout << d2 << " " << fmod (d2, 1.0) << endl;
cout << d2 << " " << (fmod (d2, 1.0) == 0) << endl;
cout.flush();
modf (d1, 0); // segfault
}
fonte
2009-10-05 19:13:39
Ci sono hack per farlo funzionare, ma il modo in cui un doppio rappresenta il suo valore significa che esso è molto probabilmente non immagazzinando un intero come pensi che lo farebbe. Può memorizzare 555 come 554.99999998 o qualcosa di divertente come quello. Non c'è modo di dirlo davvero, a meno che tu non abbia i valori di origine originali e non lo capisca da lì. float e double sono di precisione limitata. –
@ Ape-inago: In realtà, un doppio che è * assegnato * un valore intero sarà effettivamente uguale a quel valore. E l'aggiunta, la sottrazione e la moltiplicazione per i doppi a valore intrinseco producono anche un doppio con valore integrale. Tuttavia, una volta moltiplicato per un doppio arbitrario o dividendolo per un doppio, tutte le scommesse sono disattivate. – rlbond
rlbond, assumendo che il numero intero in questione sia sufficientemente piccolo. – avakar