Che differenza c'è tra il mio ed il suo...?

di il
7 risposte

Che differenza c'è tra il mio ed il suo...?

Vorrei chiedervi quale differenza c'è tra la soluzione fornita da me e quella fornita dal mio libro di testo per questo esercizio:

ESERCIZIO 5.9: arrotondamento.
Un'applicazione della funzione floor è l'arrotondamento di un valore all'intero più vicino. L'istruzione:
y = floor( x + .5 );
arrotonda il numero x all'intero più vicino ed assegna il risultato a y. Scrivete un programma che legga diversi numeri ed usi l'istruzione precedente per arrotondare ognuno di essi all'intero più vicino. Per ogni numero processato stampate sia il numero originario sia il numero arrotondato.
SOLUZIONE FORNITA DA ME:

// Codice sorgente:
#include <stdio.h>
#include <math.h>
int main( void ) {
  puts( "Questo è un programma che stampa l'arrotondamento all'intero più piccolo per ogni numero inserito, al quale viene aggiunta la quantità 0.5 prima dell'arrotondamento .\n" );
  printf( "%s", "Inserire un numero (0.0 per terminare):  " );
  double numero;
  scanf( "%lf", &numero );
  while( numero != 0 ) {
          double x = numero + 0.5;
          double y = floor( x );    
          printf( "\n%-13s%-13s%-13s", "NUMERO", "NUMERO", "NUMERO" );
          printf( "\n%-13s%-13s%-13s", "ORIGINARIO", "INCREMENTATO", "ARROTONDATO" );
          printf( "\n%-13lf%-13lf%-13lf", numero, x, floor( x ) ); 
          printf( "%s", "\n\nInserire un numero (0.0 per terminare):  " );
          scanf( "%lf", &numero ); 
  }
}
SOLUZIONE FORNITA DAL LIBRO DI TESTO:

// Soluzione dal testo:
#include <stdio.h>
#include <math.h>
void calculateFloor( void );
int main( void ) {
    calculateFloor();
}
// calculateFloor arrotonda a 5 valori
void calculateFloor( void ) {
    // ripeti per 5 input
    for( unsigned int loop = 1; loop <= 5; ++loop ) {
        printf( "%s", "Enter a floating point value:  " );
        double x;
        scanf( "%lf", &x );
        double y = floor( x + .5 );
        printf( "The rounded value is %.1f\n\n", x, y );
    }
}
Grazie. P.S. in particolare non capisco il significato di .5 in y = floor( x + .5);

7 Risposte

  • Re: Che differenza c'è tra il mio ed il suo...?

    Quello che tu fai qui

    numero + 0.5;

    lui lo fa nella chiamata di floor

    0.5 e .5 sono la stessa cosa

    Il risultato tu l'hai inserito in y, perché non usi y nella printf per visualizzare il risultato?
  • Re: Che differenza c'è tra il mio ed il suo...?

    1) questo non va bene
    while( numero != 0 )
    . coi numeri floating point non puoi fare verifiche di tipo uguaglianza, o diversità (cioè non-uguaglianza), ma solo "maggiore di" e "minore di"
    2) la soluzione del testo è fatta male, diciamo tra l'accettabile (per compilatori "intelligenti") e il dilettantistico (in ogni caso).
    in sostanza la definizione di due variabili all'interno di un ciclo for, del tutto superflue in questo caso, può (nel caso peggiore, cioè compilatore non troppo intelligente) portare ad allocazioni multiple sullo stack.
    in sostanza
    
    void calculateFloor( void ) {
            double x,y; /// l'allocazione delle variabili fuori dal codice è, in generale, cosa buona e giusta, taglio lo spiegone. normalmente è altra cosa buona e giusta inizializzarle, anche a zero, anche se poi non verranno così utilizzate.
    
        // ripeti per 5 input
        for( unsigned int loop = 1; loop <= 5; loop++ ) //nota il ++loop invece di loop++ è una presunta ottimizzazione, qui si aprirebbe uno spiegone, diciamo che in questo caso puoi fare come vuoi. in particolare notare come, corretamente, la variabile contatore è definita come UNSIGNED (non si vede spesso anche nei libri di testo)
      {
            printf( "%s", "Enter a floating point value:  " );
            scanf( "%lf", &x );
            y = floor( x + .5 );
            printf( "The rounded value is %.1f\n\n", x, y );
        }
    }
    riguardo all'effettivo funzionamento di floor poniti una questione. cos'è FLOOR, in inglese?
    sembra banale, ma come sempre è cosa ottima e giustissima riflettere un attimo su cosa stai usando, per comprendere come (forse) funzionerà.
  • Re: Che differenza c'è tra il mio ed il suo...?

    oregon ha scritto:


    Quello che tu fai qui

    numero + 0.5;

    lui lo fa nella chiamata di floor

    0.5 e .5 sono la stessa cosa

    Il risultato tu l'hai inserito in y, perché non usi y nella printf per visualizzare il risultato?
    Il vero problema, però, per me, è la differenza tra gli output delle due soluzioni: Mentre l'output della soluzione fornita dal libro di testo è: https://prnt.sc/hshti
    l'output della soluzione fornita dalla mia soluzione è: https://prnt.sc/hshsi

    Cioè: per il numero 12.5632, come si vede nei due printscreen, il LIBRO fornisce: 12.6 mentre la mia risoluzione fornisce 12.0 cioè mentre io ho utilizzato la funzione floor() per ottenere l'intero minore pù vicino al numero, il libro ha ottenuto un semplice arrotondamento alla prima cifra decimale. Però, modificando nell'esercizio il formato di stampa, cioè portandolo da .1f a f semplicemente non si ottiene assolutamente nulla. Qui il printscreen di quest'ultimo caso: https://prnt.sc/hshxk
    
    #include <stdio.h>
    #include <math.h>
    void calculateFloor( void );
    int main( void ) {
        calculateFloor();
    }
    // calculateFloor arrotonda a 5 valori
    void calculateFloor( void ) {
        // ripeti per 5 input
        for( unsigned int loop = 1; loop <= 5; ++loop ) {
            printf( "%s", "Enter a floating point value:  " );
            double x;
            scanf( "%lf", &x );
            double y = floor( x + .5 );
            printf( "The rounded value is %lf\n\n", x, y );
        }
    }
    
    Inoltre vorrei far notare che y = floor( x + .5) non incrementa x di 0.5 e lo arrotonda ma sembra arrotondare senza incrementare la x ( come si vede dai due printscreen di sopra...)
  • Re: Che differenza c'è tra il mio ed il suo...?

    +m2+ ha scritto:


    1) questo non va bene
    while( numero != 0 )
    . coi numeri floating point non puoi fare verifiche di tipo uguaglianza, o diversità (cioè non-uguaglianza), ma solo "maggiore di" e "minore di"


    riguardo all'effettivo funzionamento di floor poniti una questione. cos'è FLOOR, in inglese?
    sembra banale, ma come sempre è cosa ottima e giustissima riflettere un attimo su cosa stai usando, per comprendere come (forse) funzionerà.
    Sono d'accordo sul definire le variabili fuori dal ciclo for se queste dovessero essere di nuovo riusate fuori dal ciclo for in quanto, come si sa, le variabili definite nel ciclo for sono valide solo localmente e dunque non sono valide fuori del for.
    Per quanto riguarda la sentinella di chiusura o meglio while( numero != 0), con numero variabile float, non so come altro potrei fare per porre la condizione di terminazione del ciclo. Per fortuna anche se numero è variabile float chiude lo stesso il programma anche se ho capito il concetto di non poter porre uguaglianze o diversità tra i numeri float a causa dei possibili arrotondamenti che il calcolatore potrebbe fare, ma ripeto, per questo semplice esercizio funziona.
    Per quanto riguarda l'effettivo funzionamento della funzione floor della libreria math.h so che floor sta per pavimento e ceil per soffitto dunque il senso sarebbe quello di arrotondare all'intero più piccolo per floor ed all'intero più grande con ceil, ma il mio libro di testo ragiona come me nella teoria ma non nella risoluzione dell'esercizio, dove, tra l'altro y = floor( x + .5); non incrementa la variabile x di 0.5.... Vedi due printscrenn: https://prnt.sc/hshsi e https://prnt.sc/hshti

  • Re: Che differenza c'è tra il mio ed il suo...?

    Non sarebbe più semplice un codice del genere ( printscreen: https://prnt.sc/hsjjk )
    
    // Codice sorgente:
    #include <stdio.h>
    #include <math.h>
    int main( void ) {
      puts( "Questo è un programma che stampa l'arrotondamento all'intero più piccolo per ogni numero inserito, al quale viene aggiunta la quantità 0.5 prima dell'arrotondamento .\n" );
      printf( "%s", "Inserire un numero (0.0 per terminare):  " );
      double numero;
      scanf( "%lf", &numero );
      while( numero != 0 ) {
    
              printf( "\n%-13s%-13s", "NUMERO",  "NUMERO" );
              printf( "\n%-13s%-13s", "ORIGINARIO",  "ARROTONDATO" );
              printf( "\n%-13lf%-13.0lf", numero,  numero );
              printf( "\n%-13lf%-13.1lf", numero,  numero );
              printf( "\n%-13lf%-13.2lf", numero,  numero );
              printf( "\n%-13lf%-13.3lf", numero,  numero );          
              printf( "%s", "\n\nInserire un numero (0.0 per terminare):  " );
              scanf( "%lf", &numero ); 
      }
    }
    
    senza la funzione y = floor( x + .5); per arrotondare all'intero, ai decimi, ad i centesimi ed alle migliaia???? Non capisco perchè il mio libro di testo insiste con questa funzione floor( x + .5 ) che tra l'altro non incrementa il valore di x ma ci restituisce IL VALORE INTERO PIU' PICCOLO?!.... Il mio libro di testo inoltre continua con un altro esempio: y = floor( x * 100 + .5 ) / 100 arrotonda x alla posizione dei centesimi.... Non capisco che utilità ci sia. Se avete risposte, fornitele se vi va... Grazie e buon giorno festivo "à tous" - a tutti........
  • Re: Che differenza c'è tra il mio ed il suo...?

    Hai provato a fare qualche valutazione?
    
    floor(0.1)
    floor(0.1+0.5)
    floor(0.4)
    floor(0.4+0.5)
    floor(0.5)
    floor (0.5+0.5)
    floor (0.6)
    floor (0.6+0.5)
    
    E poi
    
    floor (132.54321 * 100 + 0.5)
    floor (132.55321 * 100 + 0.5)
    floor (0.321 * 100 + 0.5)
    floor (0.521 * 100 + 0.5)
    
    ?
  • Re: Che differenza c'è tra il mio ed il suo...?

    +m2+ ha scritto:


    Hai provato a fare qualche valutazione?
    
    floor(0.1)
    floor(0.1+0.5)
    floor(0.4)
    floor(0.4+0.5)
    floor(0.5)
    floor (0.5+0.5)
    floor (0.6)
    floor (0.6+0.5)
    
    E poi
    
    floor (132.54321 * 100 + 0.5)
    floor (132.55321 * 100 + 0.5)
    floor (0.321 * 100 + 0.5)
    floor (0.521 * 100 + 0.5)
    
    ?
    grazie per l'aiuto a comprendere meglio https://prnt.sc/hstzu
    
    // Codice sorgente:
    #include <stdio.h>
    #include <math.h>
    int main( void ) {
      puts( "Questo è un programma che stampa l'arrotondamento all'intero più vicino per ogni numero inserito, prima dell'arrotondamento .\n" );
      printf( "%s", "Inserire un numero (0.0 per terminare):  " );
      double numero;
      scanf( "%lf", &numero );
      while( numero != 0 ) {
          printf( "\n%-13s%-13s", "NUMERO",  "NUMERO" );
          printf( "\n%-13s%-13s", "ORIGINARIO",  "ARROTONDATO" );
          printf( "\n%-13lf%-13.0lf", numero,  numero );
          printf( "\n%-13lf%-13.1lf", numero,  numero );
          printf( "\n%-13lf%-13.2lf", numero,  numero );
          printf( "\n%-13lf%-13.3lf", numero,  numero );  
          
          double a = floor(0.1);
          double a1 = ceil(0.1);
          double b = floor(0.1+0.5);
          double b1 = ceil(0.1+0.5);
          double c = floor(0.4);
          double c1 = ceil(0.4);
          double d = floor(0.4+0.5);
          double d1 = ceil(0.4+0.5);
          double e = floor(0.5);
          double e1 = ceil(0.5);
          double f = floor (0.5+0.5);
          double f1 = ceil(0.5+0.5);
          double g = floor (0.6);
          double g1 = ceil(0.6);
          double h = floor (0.6+0.5);
          double h1 = ceil(0.6+0.5);
          printf( "\n\nFloor di 0.1 è:  %.3lf", a );
          printf( "\nFloor di 0.1+0.5 è:  %.3lf", b );
          printf( "\nFloor di 0.4 è:  %.3lf", c );
          printf( "\nFloor di 0.4+0.5 è:  %.3lf", d );
          printf( "\nFloor di 0.5 è:  %.3lf", e );
          printf( "\nFloor di 0.5+0.5 è:  %.3lf", f );
          printf( "\nFloor di 0.6 è:  %.3lf", g );
          printf( "\nFloor di 0.6+0.5 è:  %.3lf", h );
          printf( "\n\nCeil di 0.1 è:  %.3lf", a1 );
          printf( "\nCeil di 0.1+0.5 è:  %.3lf", b1 );
          printf( "\nCeil di 0.4 è:  %.3lf", c1 );
          printf( "\nCeilCeil di 0.4+0.5 è:  %.3lf", d1 );
          printf( "\nCeilCeil di 0.5 è:  %.3lf", e1 );
          printf( "\nCeil di 0.5+0.5 è:  %.3lf", f1 );
          printf( "\nCeil di 0.6 è:  %.3lf", g1 );
          printf( "\nCeil di 0.6+0.5 è:  %.3lf", h1 );
          
          double i = floor (132.54321 * 100 + 0.5);
          double i1 = ceil(132.54321 * 100 + 0.5);
          double l = floor (132.55321 * 100 + 0.5);
          double l1 = ceil(132.55321 * 100 + 0.5);
          double m = floor (0.321 * 100 + 0.5);
          double m1 = ceil(0.321 * 100 + 0.5);
          double n = floor (0.521 * 100 + 0.5);
          double n1 = ceil(0.521 * 100 + 0.5);
          printf( "\n\nFloor di 132.54321 * 100 + 0.5 è:  \n%.3lf\nFloor di 132.55321 * 100 + 0.5 è:  \n%.3lf\nFloor di 0.321 * 100 + 0.5 è:  \n%.3lf\nFloor di 0.521 * 100 + 0.5 è:  %.3lf", i, l, m, n );
          printf( "\n\nCeil di 132.54321 * 100 + 0.5 è:  \n%.3lf\nCeil di 132.55321 * 100 + 0.5 è:  \n%.3lf\nCeil di 0.321 * 100 + 0.5 è:  \n%.3lf\nCeil di 0.521 * 100 + 0.5 è:  %.3lf", i1, l1, m1, n1 );
    
          printf( "%s", "\n\nInserire un numero (0.0 per terminare):  " );
          scanf( "%lf", &numero ); 
      }
    }
    
Devi accedere o registrarti per scrivere nel forum
7 risposte