Non so se ci sono problemi in cui loop su grandi valori decimali per incrementi di 1 è una soluzione significativa, ma la gente può essere inciampare su questa questione alla ricerca di una soluzione per la loro infinita ciclo continuo. Pertanto, anche se la domanda chiede solo in che modo l'aggiunta è definita dallo standard, proporrò una soluzione alternativa.
In effetti, per valori elevati di f
, f++ == f
è true e l'utilizzo di tale valore come l'incremento nel ciclo avrà un comportamento non definito.
Supponendo che sia OK che f
essere incrementato di un numero che è il più piccolo numero e
superiore 1
per cui il punto mobile ha una rappresentazione f + e > f
. In tal caso, soluzione riportata di seguito in cui il ciclo sarà sempre terminare potrebbe essere OK:
// use template, or overloads for different floatingpoints
template<class T>
T add_s(T l, T r) {
T result = l + r;
T greater = std::max(l, r);
if(result == greater)
return std::nextafter(greater, std::numeric_limits<T>::max());
return result;
}
// ...
for (double f = /*...*/; f < /*...*/; f = add_s(f, 1.0))
Detto questo, l'aggiunta di piccoli carri a enormi carri allegorici si tradurrà in un cumulo di errori incontrollabile. Se ciò non è giusto per te, allora hai bisogno di matematica di precisione arbitraria, non in virgola mobile.
Spiacente, chiarito la domanda. –
Le cose si fanno strane con punti fluttuanti grandi/piccoli. I numeri in virgola mobile hanno una precisione limitata. Per numeri estremamente grandi, '1' potrebbe anche essere un errore di arrotondamento.Per numeri estremamente piccoli, '1' è così grande che potrebbe" annegare "altre cifre. –
L'operatore '++' per 'double' è definito in modo che' ++ f' è equivalente a 'f + = double (1)'. – tmlen