Problema con i floatting point

di il
14 risposte

Problema con i floatting point

Salve a tutti
spero che abbiate passato delle splendide vacanze.
premetto che in passato ho già affrontato l'argomento ma senza trovare la giusta soluzione!
così adesso ho escogitato quest' altra soluzione.
il problema del codice sottostante è il seguente:
nel secondo ciclo while o mi tronca le cifre prese 0 mi da più numeri del previsto!
esempio se introduco 123.7 mi restituisce parte previrgola ok = 123
parte post virgola 700
se invece introduco 123.7123 mi restituisce parte previrgola ok = 123
parte post virgola 712
volevo sapere come faccio a poter selezionare le cifre giuste senza che o abbia più caratteri o ne abbia di meno?
qualcosa che mi faccia capire che il numero è finito!
// cifre.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
using std::cout;
using std::cin;
//using namespaces std;
int _tmain(int argc, _TCHAR* argv[])
{
	float a;
	char t;
	int previrgola,postvirgola,indy,kindy;
        kindy=0; indy=0;
	    postvirgola=0; previrgola=0;
		//t="";
	cout << "inserisci un numero con virgola = ";
	cin >> a;
	cout << "\n\r";
	cout << "numero originale = " << a << "\n";
	// calcolo parte intera della cifra
	while ( a >=1)
	     {
			 previrgola++; a--;
	     }
	cout << "numero a metà operazione = " << a << "\n";
	while ( a > 0 )
	     {
			 postvirgola++;
			 a = a - 0.001;
	     }
        postvirgola--;
	cout << "parte pre  virgola = " << previrgola << "\n";
	cout << "parte post virgola = " << postvirgola << "\n";
	cout << "premi [invio] per terminare ";
	       cin >> t;
	return 0;
}

14 Risposte

  • Re: Problema con i floatting point

    Se ti basta poter acquisire un tot di cifre dopo la virgola puoi usare:
    cin.setprecision( numero cifre) e il manipolatore fixed.
    Vedi questo esempio.
    http://www.cplusplus.com/reference/iostream/manipulators/fixed/
  • Re: Problema con i floatting point

    Ciao shodan
    il problema essenzialmente consiste sul fatto che non c'è un numero preciso di cifre da prendere.
    perchè nell'esempio il numero viene immesso da tastiera ma nella realtà della funzione sarà il risultato di un calcolo ecco perchè mi serve capire quando una variabile termina.
  • Re: Problema con i floatting point

    Ciao smalldragon,
    l' idea di scrivere il numero in una stringa e poi separare quello che precede e segue il punto ti potrebbe andare bene?
  • Re: Problema con i floatting point

    Ciao barba
    se metto tutto in una stringa comunque ci sarebbe un primo problema sarebbe quello della dimensione della stringa.
  • Re: Problema con i floatting point

    Beh questo si può risolvere facilmente, basta sapere quale è la lunghezza massima che può avere un numero double quando viene scritto, oppure stare abbondanti e usare un buffer di 100 o 1000 caratteri
  • Re: Problema con i floatting point

    Il numero e un floating point
    poi ho provato a metterlo in una stringa in maniera diretta ma non funziona non mi da errore ma quando vado a vedere la variabile apparte un carattere iniziale non mi compare niente.
    come potrei fare ?
  • Re: Problema con i floatting point

    In questo modo puoi scrivere nella stringa senza doverla dimensionare:
    
    #include <iostream>
    #include <sstream>
    #include <string>
    using namespace std;
    
    int main()
    {
       double d = 123.45678;
    
       ostringstream stream;
       stream.precision(16);
       stream << d;
       string s = stream.str();
    
       cout << s;
    
       return 0;
    }
    
  • Re: Problema con i floatting point

    ostringstream stream;
        stream.precision(16);
        stream << a;
        string b = stream.str();
    cosi adattato
    a di tipo float
    b di tipo string
    mi da i seguenti errori:
    1>c:\documents and settings\navati\documenti\visual studio 2010\projects\cifre\cifre\cifre.cpp(31): error C2228: left of '.precision' must have class/struct/union
    1> type is 'int'
    1>c:\documents and settings\navati\documenti\visual studio 2010\projects\cifre\cifre\cifre.cpp(32): error C2297: '<<' : illegal, right operand has type 'float'
    1>c:\documents and settings\navati\documenti\visual studio 2010\projects\cifre\cifre\cifre.cpp(32): warning C4552: '<<' : operator has no effect; expected operator with side-effect
    1>c:\documents and settings\navati\documenti\visual studio 2010\projects\cifre\cifre\cifre.cpp(33): error C2374: 'b' : redefinition; multiple initialization
    1> c:\documents and settings\navati\documenti\visual studio 2010\projects\cifre\cifre\cifre.cpp(14) : see declaration of 'b'

    1>c:\documents and settings\navati\documenti\visual studio 2010\projects\cifre\cifre\cifre.cpp(33): error C2228: left of '.str' must have class/struct/union
    1> type is 'int'
    1>c:\documents and settings\navati\documenti\visual studio 2010\projects\cifre\cifre\cifre.cpp(43): error C2088: '<<' : illegal for class

    questa e linea 43:
    cout << "numero in stringa = " << b << "\n";
    questa e linea 14:
    string b;
  • Re: Problema con i floatting point

    Con i float avrai qualche problemino per via delle conversioni implicite da e verso double, per cui i risultati quasi sicuramente non saranno quelli che ti aspetti. Comunque non sono la causa degli errori che segnali.
    Ecco il programma modificato come dici tu:
    
    #include <iostream>
    #include <sstream>
    #include <string>
    using namespace std;
    
    int main()
    {
        float a = 123.45678;
    
        ostringstream stream;
        stream.precision(16);
        stream << a;
        string b = stream.str();
    
        cout << b;
    
        return 0;
    }
    
    Si compila senza problemi col Visual Studio (a parte una warning sul troncamento da double a float). Non è che hai dimenticato qualche include?
  • Re: Problema con i floatting point

    Si mi ero dimenticato l'include di sstream
    però c'è un altro problema quando faccio la copia nella stringa.
    input = 7654.8934
    output = 7654.8935546875
    le prime 3 cifre dopo il punto vanno anche bene ma la 4 cifra è errata ed il resto delle cifre e anomalo visto che non vengono inserite.
    cosa devo fare per ovviare a quest ultimo problema?
  • Re: Problema con i floatting point

    Ciao smalldragon,
    Ti sai avventurando su un terreno spinoso.

    Intanto ecco un paio di link: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html e
    Il primo è un pò pesante ma ti fa capire cosa c' è in ballo, il secondo è semplice ma interessante.

    In C++ lo standard è usare i double, quando scrivi 3.5 hai scritto una costante double, nelle librerie di sistema probabilmente vi saranno variabili double. Usando i float ti scontrerai con delle conversioni verso double che (vedi i link di prima) causeranno perdite di precisione. Un piccolo esempio:
    
       float a = 1.3; 
       double d = a;
    
    dentro 'd' troverai 1.299999952316284, se non ha motivi particolari per usare i float ti consiglio di usare i double, e anche con quelli devi stare bene attento a come li usi.
  • Re: Problema con i floatting point

    Grazie per il bel mattone di matematica spero che mi sarà utile.
    comunque credo,spero, che ci sia un modo per capire quando finisce una variabile numerica!
    con i double va bene
    ma a questo punto restano solamente 2 problemi:
    1) la stream.precision accetta anche variabili o devo metterci per forza un valore costante?
    2) come faccio a capire che valore mettere ?
    se riesco a capire ciò vedrò di scrivere un nuovo tipo di dato matematico cosi potremo finirla con tutti i vari tipi int,signed,double,float etc etc.
  • Re: Problema con i floatting point

    Se non imposti la precision nello stream vengono scritti solo tre decimali. Se imposti 16 (mi sembra sia la precisione dei double ma non sono sicuro) vengono scritte tutte le cifre (ma se sono di meno ne scrive di meno) per cui quel 16 non dovresti cambiarlo.

    Se riesci a inventare un nuovo tipo matematico che fa piazza pulita di tutti questi casini avrai la riconoscenza di tutti i programmatori e passerai alla storia!
  • Re: Problema con i floatting point

    Ci proverò
    l'idea di base c'è
    devo solo capire questi maledetti numeri con la virgola mobile ed il passaggio da numero con virgola a numero normale
    esempio di passaggio
    da 1.99999 a 2 in quanto in teoria tra un numero e un altro ci sono infini numeri cosi devo capire bene quando il computer effettua questo passaggio.
    una volta capito ciò potrò mettere in pratica con la realizzazione.
Devi accedere o registrarti per scrivere nel forum
14 risposte