|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
[c/c++]Precisione double
Ciao a tutti!
Devo dividere una variabile double per 2 ad ogni iterazione e capire quando fermarmi (cioè quando esco dallo spazio dei numeri rappresentabili). Esiste una maniera portabile di farlo? Ho provato: Codice:
#include <iostream>
int main(int argc, char **argv)
{
long double x = 2.0;
while(1) {
std::cout << x << std::endl;
x /= 2;
}
return 0;
}
Qualcuno sa come si fa? ps. il mio problema (più ampio) è di dover zoomare su un frattale fino alla massima precisione consentita dal double, quindi devo sapere quando si va oltre tale precisione.
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
A me il tuo codice funziona, ma il confronto di eguaglianza tra due double può generare problemi strani per via delle rappresentazioni/approssimazioni.
Prova così: Codice:
#include <iostream>
int main(int argc, char **argv)
{
long double x = 2.0;
long double x_2 = x/2.0;
while(x!=x_2) {
x = x_2;
x_2 /= 2.0;
std::cout << x << std::endl;
}
return 0;
}
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Ho provato la tua variazione, ma dà lo stesso comportamento. Non si ferma mai.
In effetti quello è un test che dati perturbazioni dovute all'errore di macchina potrebbe dare risultati inattesi. Sto pensando che, siccome la divisione parte sempre da 2.0 (perchè il frattale di mandelbrot è mappato su uno spazio complesso che va da (-2, -2) a (2, 2) all'inizio), posso ricercare l'ultimo valore sensato, che da me è 4.94066e-324 e fare un test su quello...quando lo raggiunge, stop. Il problema è che quel numero è sensato sulla mia macchina, ma probabilmente non su altre. Che ne dici? Non c'è una specie di INT_MAX del C per i double?? Cmq grazie della risposta
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Jan 2002
Città: In giro per il mondo
Messaggi: 107
|
Dovresiti risolvere mettendo il controllo come " if (x>= 0 && x <= 0.1) "
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Jan 2002
Città: In giro per il mondo
Messaggi: 107
|
Se poi devi confrontare due variabili in virgola mobile allora devi fare:
V3 = V1-V2 dove V3 è la differenza tra le due variabili V1 e V2 e poi devi confrontare così " if (V3 >= - 0.1 && V3 <= 0.1) " dove -0.1/0.1 è un range di tollerabilità. Ou revoir!!! |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Trovato! La classe numeric_limits è venuta in soccorso! Per chi fosse interessato, ecco la soluzione elegante
Codice:
#include <iostream>
#include <limits>
int main(int argc, char **argv)
{
long double x = 2.0;
long double limit = std::numeric_limits<long double>::min();
while(x >= limit) {
std::cout << x << std::endl;
x /= 2.0;
}
return 0;
}
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
|
|
|
|
|
#7 | |
|
Member
Iscritto dal: Jan 2002
Città: In giro per il mondo
Messaggi: 107
|
Quote:
1) E' utilizzabile anche scrivendo codice in C; 2) E' utilizzabile anche quando non devi per forza iterare fino a zero o confrontare con zero, ma devi semplicemente confrontare un valore in virgola mobile con un altro. Comunque in generale la regola di confronto tra valori in virgola mobile è confrontare un valore con un range di due valori. Au revoir! |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 05:36.



















