Il doppio ha un intervallo superiore a un numero intero a 64 bit, ma la sua precisione è inferiore alla sua rappresentazione (poiché il doppio è anche 64 bit, può montare più valori effettivi). Quindi, quando si rappresentano interi più grandi, si inizia a perdere la precisione nella parte intera.Trova la dimensione massima integer che un tipo a virgola mobile può gestire senza perdita di precisione
#include <boost/cstdint.hpp>
#include <limits>
template<typename T, typename TFloat>
void
maxint_to_double()
{
T i = std::numeric_limits<T>::max();
TFloat d = i;
std::cout
<< std::fixed
<< i << std::endl
<< d << std::endl;
}
int
main()
{
maxint_to_double<int, double>();
maxint_to_double<boost::intmax_t, double>();
maxint_to_double<int, float>();
return 0;
}
Questo stampa:
2147483647
2147483647.000000
9223372036854775807
9223372036854775800.000000
2147483647
2147483648.000000
notare come max int
può inserirsi in un double
senza perdita di precisione e boost::intmax_t
(64-bit in questo caso) non può. float
non può nemmeno contenere un int
.
Ora, la domanda: esiste un modo in C++ per verificare se l'intero intervallo di un determinato tipo intero può adattarsi a un tipo di punto di loating senza perdita di precisione?
Preferibilmente,
- sarebbe un controllo della fase di compilazione che può essere utilizzato in un asserzione statica,
- e non comporterebbe enumerare le costanti compilatore deve sapere o può calcolare.
Perché devi controllare? La parte intera ha 52 bit di precisione, quindi è quanto ottieni. –
Una volta determinato il limite, non puoi semplicemente definire un CONST? –
@Billy: _Technically_ C++ non richiede IEEE 754 in virgola mobile, quindi supponendo che l'implementazione utilizzi IEEE 754 non è portatile (il fatto che IEEE 754 sia onnipresente nonostante). –