Domanda

Ho battuto la testa su questo per tutto il giorno. Il progetto C ++ a cui sto attualmente lavorando ha l'obbligo di visualizzare un valore modificabile. La cifra attualmente selezionata visualizza il valore incrementato sopra e il valore decrementato sotto per quella cifra. È utile poter fare riferimento al valore modificabile sia come numero sia come raccolta di cifre. Sarebbe fantastico se ci fosse una forma indicizzabile di un numero in virgola mobile, ma non sono stato in grado di trovare una soluzione del genere. Sto lanciando questa domanda là fuori per vedere se c'è qualcosa di ovvio che mi manca o se dovrei semplicemente rotolare la mia.


Grazie per il consiglio! Speravo in una soluzione che non si convertisse da float - > stringa - > int, ma penso che sia il modo migliore per sfuggire ai problemi di quantizzazione in virgola mobile. Ho finito per andare con boost :: format e facendo solo riferimento ai singoli caratteri della stringa. Non riesco a vedere che sia un'enorme differenza di prestazioni rispetto all'utilizzo di combinazioni di modf e fmod per tentare di ottenere una cifra da un float (probabilmente lo fa proprio dietro le quinte, solo più saldamente della mia implementazione).

È stato utile?

Soluzione

La rappresentazione interna dei numeri in virgola mobile non è come si vede. Puoi solo lanciarti in eccitazione.

Per trasmettere, procedere come segue:

char string[99];
sprintf(string,"%f",floatValue);

Oppure vedi questo: http: // www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.1

L'articolo di Wikipedia può spiegare di più sulla rappresentazione: http://en.wikipedia.org/wiki/ floating point

Altri suggerimenti

Oh, ci sono molti modi per convertire in una stringa. ( Anche se preferisco s n printf () me stesso.)

Oppure potresti convertire in un int ed estrarre le cifre con modulo e divisione intera. Puoi contare il numero di cifre con il log {base10}.

(Ricorda: log {baseA} _X / log {baseA} _B = log {baseB} _X.)

Esempio:

#define SHOW(X) cout << # X " = " << (X) << endl

int
main()
{
  double d = 1234.567;

  SHOW( (int(d)%10000) / 1000 );
  SHOW( (int(d)%1000)  / 100  );
  SHOW( (int(d)%100)   / 10   );
  SHOW( (int(d)%10)           );
  SHOW( (int(d*10)  % 10)     );
  SHOW( (int(d*100) % 10)     );
  SHOW( (int(d*1000)% 10)     );

  SHOW( log(d)/log(10) );
}

Anche se dovresti usare static_cast ...

Fai attenzione alla notazione esponenziale. Con un numero molto grande o molto piccolo, potresti avere un problema.

I numeri in virgola mobile hanno anche problemi di arrotondamento che possono causare dolore. (È lo stesso motivo per cui non utilizziamo l'operatore == tra due doppie. O perché non puoi fare affidamento su a * b == b * a. A seconda dei valori esatti di a & amp; b, potrebbero differire molto leggermente fuori intorno a 10 ^ -25.)

Puoi eseguire il cast tra stringa e float solo usando boost :: lexical_cast. Tuttavia, non è possibile indicizzare direttamente il modulo float: non è memorizzato internamente come cifre decimali. Questo probabilmente non è un grosso problema. Per la tua UI, molto probabilmente manterrai comunque una stringa del numero, con conversioni da e verso float nel getter / setter.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top