Torna indietro   Hardware Upgrade Forum > Software > Programmazione

OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum
OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum
Abbiamo partecipato all'OVHcloud Summit 2025, conferenza annuale in cui l'azienda francese presenta le sue ultime novità. Abbiamo parlato di cloud pubblico e privato, d'intelligenza artificiale, di computer quantistici e di sovranità. Che forse, però, dovremmo chiamare solo "sicurezza"
Un mostro da MSI: QD-OLED WQHD a 500 Hz con AI Care e DisplayPort 2.1a
Un mostro da MSI: QD-OLED WQHD a 500 Hz con AI Care e DisplayPort 2.1a
Abbiamo potuto mettere le mani in anteprima sul nuovo monitor MSI dedicato ai giocatori: un mostro che adotta un pannello QD-OLED da 26,5 pollici con risoluzione 2560 x 1440 pixel, frequenza di aggiornamento fino a 500 Hz e tempo di risposta di 0,03 ms GtG
DJI Neo 2 in prova: il drone da 160 grammi guadagna il gimbal e molto altro
DJI Neo 2 in prova: il drone da 160 grammi guadagna il gimbal e molto altro
DJI aggiorna la sua linea di droni ultraleggeri con Neo 2, un quadricottero da 160 grammi che mantiene la compattezza del predecessore ma introduce una stabilizzazione meccanica a due assi, sensori omnidirezionali e un sistema LiDAR
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 08-05-2010, 11:22   #1
Dari
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);
}
A questo punto succede quello che non capisco: se il numero che devo convertire come percentuale massima è 0.1, il risultato in massimo è 9 anziché 10, in più questo succede solo dentro questo programma, ho provato a "isolare" il pezzo di codice in un programma diverso e stampa 10:
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;
}
L'output che ho è:
Codice:
10 0.1
Non riesco a capire se ho il prosciutto sugli occhi io e c'è qualcosa che non vedo...se qualcuno riesce a capire cosa c'è che non va mi fa un grandissimo favore.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 08-05-2010, 14:21   #2
cionci
Senior Member
 
L'Avatar di cionci
 
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
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 08-05-2010, 14:48   #3
Dari
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.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 11:35   #4
cionci
Senior Member
 
L'Avatar di cionci
 
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
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 13:51   #5
Dari
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).
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 16:25   #6
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Bisogna allora vedere come è stato calcolato...
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 16:48   #7
Dari
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.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 16:59   #8
cionci
Senior Member
 
L'Avatar di cionci
 
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.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 17:25   #9
Dari
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.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 17:29   #10
cionci
Senior Member
 
L'Avatar di cionci
 
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 ?
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 17:44   #11
Dari
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.*/
ps grazie mille, se non si può fare così vedrò di trovare un altro modo, però non so proprio come trattare le percentuali se non come double.

Ultima modifica di Dari : 09-05-2010 alle 17:46.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 18:04   #12
cionci
Senior Member
 
L'Avatar di cionci
 
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;
}
A me stampa 10...
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 18:29   #13
Dari
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.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 18:35   #14
cionci
Senior Member
 
L'Avatar di cionci
 
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();
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 19:16   #15
Dari
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;
}
In pratica ho spostato li dentro la sottrazione che facevo.
Succede sempre la stessa cosa però.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 19:25   #16
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Cambia poco, quotaAcquistata come lo calcoli ?
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 19:56   #17
Dari
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!
Dari è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum OVHcloud Summit 2025: le novità del cloud...
Un mostro da MSI: QD-OLED WQHD a 500 Hz con AI Care e DisplayPort 2.1a Un mostro da MSI: QD-OLED WQHD a 500 Hz con AI C...
DJI Neo 2 in prova: il drone da 160 grammi guadagna il gimbal e molto altro DJI Neo 2 in prova: il drone da 160 grammi guada...
L'IA "seria" di Appian è diversa: inserita nei processi e rispetta dati e persone L'IA "seria" di Appian è divers...
Polestar 3 Performance, test drive: comodità e potenza possono convivere Polestar 3 Performance, test drive: comodit&agra...
Black Friday e Apple: qui tutte le offer...
Il CEO di Epic contro l'etichetta 'conte...
A causa di un problema durante il lancio...
Per il responsabile delle Porsche 911 e ...
Ritorno di fiamma tra Apple e Intel: gal...
Horses è stato 'bannato': l'horro...
Truffe finanziarie sui social, scatta il...
Tesla inaugura a Busto Arsizio la postaz...
Barriere autostradali fotovoltaiche: Ana...
Accordo Gruppo FS-Microsoft: l'IA dell'a...
Prezzo mai visto: le Sony WH-1000XM5 Spe...
Microsoft amplierà il suo laborat...
ECOVACS DEEBOT T30C OMNI GEN2 a 349€: co...
Super offerta Amazon: HP OMEN MAX 16 con...
L'offerta nascosta di Very Mobile fa gol...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 09:02.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v