Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Ecovacs Goat O1200 LiDAR Pro: la prova del robot tagliaerba con tagliabordi integrato
Ecovacs Goat O1200 LiDAR Pro: la prova del robot tagliaerba con tagliabordi integrato
Nuova frontiera per i robot tagliaerba, con Ecovacs GOAT O1200 LiDAR Pro che riconosce l'ambiente in maniera perfetta, grazie a due sensori LiDAR, e dopo la falciatura può anche rifinire il bordo con il tagliabordi a filo integrato
Recensione Samsung Galaxy S26+: sfida l'Ultra, ma ha senso di esistere?
Recensione Samsung Galaxy S26+: sfida l'Ultra, ma ha senso di esistere?
Equilibrio e potenza definiscono il Samsung Galaxy S26+, un flagship che sfida la variante Ultra e la fascia alta del mercato con il primo processore mobile a 2nm. Pur mantenendo l'hardware fotografico precedente, lo smartphone brilla per un display QHD+ da 6,7 pollici d'eccellenza, privo però del trattamento antiriflesso dell'Ultra, e per prestazioni molto elevate. Completano il quadro la ricarica wireless a 20W e, soprattutto, un supporto software settennale
Zeekr X e 7X provate: prezzi, autonomia fino a 615 km e ricarica in 13 minuti
Zeekr X e 7X provate: prezzi, autonomia fino a 615 km e ricarica in 13 minuti
Zeekr sbarca ufficialmente in Italia con tre modelli elettrici premium, X, 7X e 001, distribuiti da Jameel Motors su una rete di 52 punti vendita già attivi. La Zeekr X parte da 39.900 euro, la 7X da 54.100: piattaforma a 800V, chip Snapdragon di ultima generazione, ricarica ultraveloce e un'autonomia dichiarata fino a 615 km WLTP. Le prime consegne sono previste a metà aprile
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 08-05-2010, 10: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, 13: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, 13: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 14:16.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 10: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, 12: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, 15: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, 15: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 16:00.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 15: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, 16: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, 16: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, 16: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 16:46.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 17: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, 17: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 17:35.
Dari è offline   Rispondi citando il messaggio o parte di esso
Old 09-05-2010, 17: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, 18: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, 18: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, 18: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


Ecovacs Goat O1200 LiDAR Pro: la prova del robot tagliaerba con tagliabordi integrato Ecovacs Goat O1200 LiDAR Pro: la prova del robot...
Recensione Samsung Galaxy S26+: sfida l'Ultra, ma ha senso di esistere? Recensione Samsung Galaxy S26+: sfida l'Ultra, m...
Zeekr X e 7X provate: prezzi, autonomia fino a 615 km e ricarica in 13 minuti Zeekr X e 7X provate: prezzi, autonomia fino a 6...
Marathon: arriva il Fortnite hardcore Marathon: arriva il Fortnite hardcore
HP Imagine 2026: abbiamo visto HP IQ all’opera, ecco cosa può (e non può) fare HP Imagine 2026: abbiamo visto HP IQ all’opera, ...
Le 10 migliori offerte Amazon di Pasqua:...
Nuove fotografie dagli astronauti di Art...
La toilette della capsula Orion Integrit...
GeForce NOW: ecco tutte le novità in arr...
Il Realme 16 5G debutta sul mercato glob...
HONOR svela tre nuovi tablet: il più int...
Tineco Floor One S9 Master: aspira e pul...
Vivo X300 Ultra, il lancio globale è ini...
Offerte robot aspirapolvere Amazon: ECOV...
L'AI genera codice in 8 minuti e i senio...
Ring Intercom Audio a 44,99€ su Amazon: ...
Apple iPhone 16 crolla a 689€: ecco perc...
Google Pixel 9 a 449,90€ con caricatore ...
Ecco la top 7 delle offerte Amazon, aggi...
Ex ingegnere ammette il sabotaggio: migl...
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: 20:36.


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