|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Nov 2008
Messaggi: 138
|
[C++] Valore dello static_cast sbagliato
Ho un problema in un programma dove avrei bisogno di troncare un double per assegnare la parte intera ad un int. In pratica mi arriva un numero fra 0 e 1, che rappresenta una percentuale, io voglio scriverla "normalmente" come numero fra 0 e 100, per cui moltiplico il numero che arriva per 100 e lo converto in int con lo static_cast, in questo modo:
Codice:
f(double percentualeDiPartenza_, double percentualeMassima_) {
int minimo, massimo;
double percentualeDiPartenzaInCentesimi = percentualeDiPartenza_*100.0, percentualeMassimaInCentesimi = percentualeMassima_*100.0;
minimo = static_cast<int>(percentualeDiPartenzaInCentesimi);
massimo = static_cast<int>(percentualeMassimaInCentesimi);
}
Codice:
#include <iostream>
using std::cout;
using std::endl;
int main() {
int numero;
double numero2 = 0.1;
numero = static_cast<int>(numero2*100.0);
cout << numero << ' ' << numero2 << endl;
}
Codice:
10 0.1 |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Prova con 0.1L al posto di 0.1 e 100.0L al posto di 100.0
|
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Nov 2008
Messaggi: 138
|
Quindi è tipo una perdita di precisione? Ma 100.0 non viene convertito a double automaticamente? Ora provo comunque, grazie.
Aggiornamento: ho messo la L dopo tutte le costanti numeriche coinvolte, anche quelle nel codice che chiama la funzione, purtroppo non è cambiato nulla, altri suggerimenti? p.s. ma c'è qualche differenza fra il codice del main che ho messo e quello della funzione f? Non riesco a capire come mai si comportino diversamente. Ultima modifica di Dari : 08-05-2010 alle 15:16. |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Sinceramente non mi ricordo, ma mi sembra che s enon specifichi il formato venga usato float di default.
Se metti L, la costante è un long double a 80 bit. 100.0 viene convertito automaticamente a double, il problema però non dovrebbe essere 100, che ha una rappresentazione esatta anche su un float, ma 0.1 |
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Nov 2008
Messaggi: 138
|
Si ma il fatto è che 0.1 non da problemi, infatti il secondo pezzo di codice funziona, quello che non funziona è la funzione f quando al posto di uno dei due parametri arriva 0.1 (che viene calcolato da un'altra parte direttamente come double).
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Bisogna allora vedere come è stato calcolato...
|
|
|
|
|
|
#7 |
|
Member
Iscritto dal: Nov 2008
Messaggi: 138
|
Il valore che passo alla funzione* è 1.0L meno un double x che può valere 0.9, 0.8, 0.7, 0.6, 0.5 (in input si seleziona uno fra dei valori fissi). Il problema sorge quando è 0.9, dei valori sono sicuro perché ho messo un cout per ogni variabile per vedere cosa succede. Se faccio stampare i valori coinvolti in:
percentualeDiPartenzaInCentesimi = percentualeDiPartenza_*100.0L ottengo 10 e 0.1, se faccio stampare minimo = static_cast<int>(percentualeDiPartenzaInCentesimi); ottengo 9, se c'è di mezzo qualche conversione a float non so proprio dove sia, il tipo float non lo uso da nessuna parte e ho messo la L dopo tutte le costanti reali. *È in una funzione che ha solo un return 1.0L - x come codice. Ultima modifica di Dari : 09-05-2010 alle 17:00. |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Stampa percentualeDiPartenzaInCentesimi ed avrai la tua risposta... Comunque è un problema di rappresentazione.
1 - 0.9 non fa 0.1 in floating point o meglio...non fa esattamente 0.1, ma magari 0.0999999, con il risultato che se fai il troncamento ottieni 9. |
|
|
|
|
|
#9 |
|
Member
Iscritto dal: Nov 2008
Messaggi: 138
|
Stampa 10 come ho scritto prima, e se stampo minimo invece stampa 9, mi sembra assurdo ma è così. E la cosa più assurda è che nel programma che ho scritto nell seconda parte del primo post lo stesso calcolo dà 10.
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Mi posti tutto il codice, anche quello che usi per passare i valori alla funziona ?
|
|
|
|
|
|
#11 |
|
Member
Iscritto dal: Nov 2008
Messaggi: 138
|
È un po' un casino mettere tutto, cmq ecco:
Codice:
double percentualeMassima_ = 0.5L - getParteNonDisponibile(); /*dentro la funzione getParteNonDisponibile() c'è return 1.0L - x, con x che può valere 0.9-0.5*/ f(0.0L, percentualeMassima_); /* la f è quella di prima, il codice non è esattamente così perché è il costruttore di un oggetto, è troppo lungo metterlo tutto e il resto non c'entra con il calcolo, le variabili in f vengono modificate solo nel codice che ho messo.*/ Ultima modifica di Dari : 09-05-2010 alle 17:46. |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Una cosa del genre quindi ?
Codice:
#include <iostream>
using namespace std;
void f(double percentualeDiPartenza_, double percentualeMassima_) {
int minimo, massimo;
double percentualeDiPartenzaInCentesimi = percentualeDiPartenza_*100.0L, percentualeMassimaInCentesimi = percentualeMassima_*100.0;
minimo = static_cast<int>(percentualeDiPartenzaInCentesimi);
massimo = static_cast<int>(percentualeMassimaInCentesimi);
cout << minimo << " " << massimo << endl;
}
int main()
{
double percentualeMassima_ = 0.5L - 0.4L;
f(0.0L, percentualeMassima_);
return 0;
}
|
|
|
|
|
|
#13 |
|
Member
Iscritto dal: Nov 2008
Messaggi: 138
|
anche a me se lo metto in un programma separato (vedi primo post, il secondo pezzo di codice), boh, può dipendere da qualche opzione del compilatore? Ho -Wl,-O1 -L/usr/lib -lQtGui -lQtCore -lpthread (è un'applicazione Qt).
Aggiornamento: dopo cambio la rappresentazione interna dei valori in modo da minimizzare sottrazioni e altro. Ultima modifica di Dari : 09-05-2010 alle 18:35. |
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Credo che dipenda tutto da cosa ritorna getParteNonDisponibile();
|
|
|
|
|
|
#15 |
|
Member
Iscritto dal: Nov 2008
Messaggi: 138
|
ParteNonDisponibile ha solo una sottrazione dentro, fra la costante 1.0L e un campo dati double con valori fissi perchè li inserisco interi da uno spinBox e li converto in double...volendo potrei cambiare la rappresentazione di tutte le percentuali da double a int ma sarebbe una porcheria, anche perchè i calcoli li devo fare in double lo stesso.
Adesso ho leggermente cambiato il codice, al posto di parteNonDisponibile() uso getParteDisponibile(): Codice:
double getParteDisponibile() const {
return 0.5L - quotaAcquistata;
}
Succede sempre la stessa cosa però. |
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Cambia poco, quotaAcquistata come lo calcoli ?
|
|
|
|
|
|
#17 |
|
Member
Iscritto dal: Nov 2008
Messaggi: 138
|
Ho risolto, il problema (non so perché) era nella lettura del valore di quotaAcquistata come int dallo spinBox, ho usato un doubleSpinBox (non avevo visto che c'era anche quello) e funziona tutto, grazie mille per l'assistenza!
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 09:02.



















