Pagina 2 di 2 primaprima 1 2
Visualizzazione dei risultati da 11 a 19 su 19

Hybrid View

  1. #1
    me lo puoi postare così evito perdite di tempo inutili perfavore?
    visitate www.linkutility.it !!! Il sito per ogni necessità

  2. #2
    NSString *test1 = [NSString stringWithFormat:@"%.16f", d1];
    giusto? Per le operazioni sulle stringhe mi sapresti indicare una pagina web o guida che illustra bene o quasi tutto ciò che devo sapere?
    Grazie mille per l'interessamento
    visitate www.linkutility.it !!! Il sito per ogni necessità

  3. #3
    La domanda che fai in realtà non ha una soluzione "vera" per un motivo molto semplice: nel momento in cui memorizzi un numero decimale in un double la partita è persa, non puoi più dire esattamente dove terminava il numero "originale".

    Prova a stampare 0.1 a 100 cifre decimali (usando ad esempio printf("%.100f", 0.1)): l'output sarà del tipo
    codice:
    0.1000000000000000055511151231257827021181583404541015625000000000000000000000000000000000000000000000
    Questo accade perché i double memorizzano i numeri in binario, e molti numeri razionali che hanno un'espansione decimale finita (come ad esempio 0.1) in binario sono numeri periodici (0.1dec = 0.00011001100110011(0011)... bin). I double ovviamente hanno una mantissa finita (di 53 bit), per cui il numero in questione viene arrotondato alla 53esima cifra dopo la virgola, producendo un risultato inaccurato.

    Ora, data questa intrinseca imprecisione come può sapere la printf nel momento in cui le passi un certo numero se tu intendevi precisamente quel numero lì, oppure se quello che vede è il risultato di un arrotondamento di un numero decimale? Ovvero, come fa a dire "in 0.1 le cifre finiscono lì, non serve stampare altro" se in realtà il numero che riceve lei va avanti per altre 30 cifre decimali che non sono zeri?

    Per questo motivo, printf, se non viene fornito alcuno specificatore di numero di cifre decimali, arrotonda sulla sesta cifra decimale, dato che viene presa come riferimento la precisione di un float, che è di circa 7 cifre decimali (ha 24 bit di mantissa, per cui log10(2^-24)=-7,22); stampare cifre oltre questa precisione per un float corrisponde a stampare fuffa, e analogamente stampare oltre 15 cifre decimali per un double.

    Il problema di %.<precisione>f è che, se gli specifichi un numero di cifre decimali da stampare, provvede a stamparle tutte anche se sono zeri (a differenza di %f "naturale", che arrotonda a 6 cifre ma ne stampa meno se possibile).

    Fondamentalmente, ci sono due soluzioni semplici:
    - usare %g; %g consente di specificare la precisione massima da impiegare, per cui se usi "%.12g" (precisione massima sensata da usare per dei double) arrotonderà alla 12esima cifra decimale, non stampando gli zeri finali se non sono seguiti da alcuna cifra diversa da zero; il problema di %g è che in "determinate" circostanze (se il numero è troppo grosso o troppo piccolo) può passare alla rappresentazione esponenziale, il che può non essere sempre desiderato;
    - usare %.15f con sprintf (o analoghe funzioni Objective C, stringWithFormat segue in gran parte le specifiche printf salvo qualche aggiunta) per stampare il numero all'interno di una stringa (come ti è stato suggerito), quindi scorrere la stringa da destra verso sinistra uccidendo tutti i caratteri finché non si incontra qualcosa di diverso da zero.
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    Grazie MItaly per la tua spiegazione! comunque fmeggysax appena torno a casa scrivo la funzione che potresti usare e te la posto allora

    Per le pagine web peró non ti so dire molto siccome a me piace da sempre il c++ e quindi con il c ho solo imparato le basi e qualcosa di più avanzato ma le funzioni non me le ricordo bene... Comunque una veloce ricera del tipo : "string c" dovrebbe fornirti i risultati da te desiderati.
    Ultima modifica di maluz1; 23-11-2013 a 08:17

  5. #5
    Concordo con maluz1! Grande Mitaly quando torno a casa provo con %g altrimenti aspetto maluz1 che mi aiuta con quel codice :3
    visitate www.linkutility.it !!! Il sito per ogni necessità

  6. #6
    ciao fmeggysax, oggi ho implementato il codice usando il c e mi sono quasi fuso il cervello. all'inizio andava praticamente alla perfezione fino a quando ottenevo risultati errati in alcuni casi: così ho riscritto la funzione pow della math.h e tutto andava correttamente fino a quando un'altra eccezione si è verificata: con 0.123 veniva perfetto, con 0.234 una roba illeggibile. così ho riscritto anche la trunc ma sostituendo non so perchè ma non risultava. questa sarà la mia ultima esperienza con il c!

    a parte gli scherzi il codice te lo posto ma riguardatelo soprattutto con le conversioni:

    codice:
    #include <stdio.h>
    #include <math.h>
    
    
    int new_trunc( double n )
    {
      int x= 0;
    
    
      while( ( n > x ) && ( n > x + 1) )
        x++;
    
    
      return x;
    }
    
    
    int new_pow( int base, int esp )
    {
      int pot= 1;
      int i;
    
    
      for ( i= 0; i < esp; i++ )
        pot*= base;
    
    
      return pot;
    }
    
    
    char* double_to_str( double p_dec, char* str )
    {
      int p_dec_int= 0;
      int i= 0;
      int n_dec= 0;            // numero cifre decimali
      int div;
    
    
      while( p_dec != trunc( p_dec ) )
      {                                // lo rendo senza virgola
        p_dec*= 10;
        n_dec++;
      }
    
    
      p_dec_int= p_dec;
      n_dec--;
    
    
      while( n_dec >= 0 )
                                      //memorizzo in str le singole cifre trasformandole da int a carattere ascii
        div= new_pow( 10, n_dec );
    
    
        if ( n_dec == 0 )
          div= 1;
    
    
        str[i]= (char) ( p_dec_int/div + 48 );
        p_dec_int= p_dec_int - ( ( p_dec_int / div ) * div );
    
    
        n_dec--;
        i++;
      }
    
    
      return str;
    }
    
    
    main()
    {
      const int DIM_DEC_DOUBLE= 16;   // qui ci metti il limite di cifre che vuoi controllare( per eliminare gli 0 )
      int i;
      double n;
      int p_int;
      double p_dec;
      char s[DIM_DEC_DOUBLE];
    
    
      for( i= 0; i < DIM_DEC_DOUBLE; i++ )  //inizializzo il vettore
        s[i]= ' ';
    
    
      scanf("%lf", &n );
    
    
      p_int= trunc( n );   // parte intera del numero
      p_dec= n - p_int;    // parte decimale del numero
    
    
      printf("%d,%s\n", p_int, double_to_str( p_dec, s ) );
    }
    lavoraci un pò, scusami per averti illuso anche se poi alla fine il codice è quello... almeno la logica è quella ciao!

  7. #7
    Quote Originariamente inviata da maluz1 Visualizza il messaggio
    ...
    Mi sembra che tu ti sia complicato un po' la vita inutilmente, oltre al fatto che ad occhio non gestisci correttamente un paio di corner case... il problema comunque si può risolvere in maniera relativamente semplice delegando il grosso del lavoro alla printf:
    codice:
    int fprintdouble(FILE *stream, double num, unsigned int maxPrecision)
    {
        char buf[16];
        char *bufPtr=buf, *ptr;
        int len=snprintf(buf, sizeof(buf), "%.*f", maxPrecision, num);
        if(len<=0)
            return len;
        else if(len>=sizeof(buf))
        {
            bufPtr=malloc(len+1);
            if(bufPtr==NULL)
                return -1;
            snprintf(bufPtr, len+1, "%.*f", maxPrecision, num);
        }
        for(ptr=bufPtr+len-1; ptr>=bufPtr && *ptr=='0'; ptr--)
            *ptr='\0';
        if(*ptr=='.')
            *ptr='\0';
        fputs(bufPtr, stream);
        if(buf!=bufPtr)
            free(bufPtr);    
        return len;
    }
    
    int printdouble(double num, unsigned int maxPrecision)
    {
        fprintdouble(stdout, num, maxPrecision);
    }
    La parte vagamente ingarbugliata è la questione della malloc (per gestire il caso in cui la stringa sia più lunga del buffer allocato localmente), ma per il resto è abbastanza semplice capire come funziona.
    Ultima modifica di MItaly; 24-11-2013 a 16:48
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    D: ma a me serve per object c proprio perché non lo conosco bene... mentre c e java gli conosco comunque grazie mille
    visitate www.linkutility.it !!! Il sito per ogni necessità

  9. #9
    Wow... Mitaly io non avrei mai fatto un codice del genere be complimenti...!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.