Prima di tutto, è necessario assicurarsi di stampare effettivamente un numero sufficiente di cifre per garantire che vengano visualizzati tutti i valori rappresentabili di double
. È possibile farlo nel modo seguente (assicuratevi di #include <iomanip>
per questo):
std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << getMax(a) << std::endl;
In secondo luogo, numeric_limits<>::min
non è appropriato per questo. Se il valore iniziale è 1.0
, è possibile utilizzare numeric_limits<double>::epsilon
, che è la più piccola differenza da 1.0
che è rappresentabile.
Tuttavia, nell'esempio di codice, il valore iniziale è 32
. Epsilon non funziona necessariamente per questo. Calcolare l'epsilon corretto in questo caso è difficile.
Tuttavia, se è possibile utilizzare C++ 11 (*), c'è una funzione nell'intestazione cmath
che fa quello che è necessario std::nextafter
:
#include <iostream>
#include <limits>
#include <iomanip>
#include <cmath>
double getMax(double a)
{
return std::nextafter(a,std::numeric_limits<double>::lowest());
}
int main()
{
double a = 32;
std::cout << std::scientific
<< std::setprecision(std::numeric_limits<double>::max_digits10)
<< getMax(a)
<< std::endl;
return 0;
}
ho messo sul liveworkspace .
Per spiegare:
double nextafter(double from, double to);
restituisce il valore successivo rappresentabili del dal in direzione di a. Quindi ho specificato std::numeric_limits<double>::lowest()
nella mia chiamata per assicurarmi di ottenere il successivo valore rappresentabile inferiore all'argomento.
(*) Vedere il commento di Tony D qui sotto. Potresti avere accesso a nextafter()
senza C++ 11.
Tutto ciò che viene detto, 'getMax' non ha senso per gli intervalli aperti e [' getSup'] (http://en.wikipedia.org/wiki/Supremum) dovrebbe restituire esattamente 1. –