Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    exp(x) risultati diversi su pc diversi

    Sul mio pc, windows, con codeblocks (compilatore mingw), se scrivo exp(50) esce un numero grande del tipo:

    xxxxxxxxxxxxxxxx0000000.0000000000000 (dove gli x sono numeri)

    Su un altro pc, ubuntu, con codeblocks (compilatore gcc), se scrivo exp(50) invece esce:

    xxxxxxxxxxxxxxxxxxxxxxxx.0000000000000


    Ora, apparte gli zeri dopo la virgola che penso siano normali per l'approssimazione, come si spiega la significativa differenza sulle ultime cifre?!?

    Grazie

  2. #2
    Posta il codice che usi.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    niente di particolare, quella è la cosa strana...

    codice:
    #include <stdio.h>
    #include <math.h>
    
    int main()
    {
       printf("%.10lf\n", exp(50));
    
       return 0;
    }
    è un codice banalissimo! compilato sul mio pc fa una cosa, compilato sull'altro pc ne fa un'altra.....

  4. #4
    Se metti 50.0 invece di 50 cambia qualcosa? Cosa restituisce sizeof(double) sulle due macchine?
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    sizeof(double) è 8 su entrambe, e 50 o 50.0 dà lo stesso risultato... non riesco a spiegarmi questa enorme discrepanza... a te cosa stampa exp(50)?

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    a me

    Windows 7 32 bit compilatore dev-C++:

    xxxxxxxxxxxxxxxx000000.0000000000

    Le x e gli 0 non sono messi a caso, ho contato i numeri e gli zeri perfettamente..

  7. #7
    Se può interessare:

    codice:
    anto@anto-net:~/desktop$ gcc --version
    gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
    Copyright (C) 2009 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    anto@anto-net:~/desktop$ gcc main.c -o main && ./main
    5184705528587072045056.0000000000

  8. #8
    L'errore sta nello specificatore passato a printf: "%lf" non esiste (mentre "%Lf" è riservato per i long double), mentre per i double si usa il normale "%f". I float non sono contemplati, dal momento che, quando passati a funzioni variadic, sono promossi in automatico a double, così come tutti i tipi più piccoli di int sono promossi a int.

    Ad insospettirmi in effetti è stato l'output di gcc
    codice:
    matteo@teoubuntu:~/cpp/test$ gcc -O3 -Wall -Wextra -ansi -pedantic exp.c -o exp.x
    exp.c: In function ‘main’:
    exp.c:6: warning: ISO C90 does not support the ‘%lf’ gnu_printf format
    che mi ha fatto riguardare bene la manpage, che non parla da nessuna parte di float, ma cita il "%Lf"; una rapida ricerca ha confermato i miei sospetti.
    Non ho idea di cosa venisse fuori da MinGW su Windows, ma qualunque cosa fosse era accettabile per lo standard, dato che veniva specificata una stringa di formattazione non valida.

    Comunque, ancora una volta si conferma che il sistema di formattazione della printf è piuttosto fragile; grazie a dio nella maggior parte dei casi in C++ l'overloading dell'operatore << ci salva.

    Ah, qualora qualcuno ancora si chiedesse quanto fa e^50:
    codice:
    #include <stdio.h>
    #include <math.h>
    
    int main()
    {
       printf("%.10f\n", exp(50));
    
       return 0;
    }
    codice:
    matteo@teoubuntu:~/cpp/test$ gcc -O3 -Wall -Wextra -ansi -pedantic exp.c -o exp.x
    matteo@teoubuntu:~/cpp/test$ ./exp.x 
    5184705528587072045056.0000000000
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Grazie per le precisazioni, ma qualcosa ancora non torna (su windows, su ubuntu sembra tutto ok):

    Il codice
    codice:
    include <stdio.h>
    #include <math.h>
    
    int main()
    {
       printf("%.10f\n", exp(50));
    
       return 0;
    }
    ancora ritorna
    codice:
    5184705528587072000000.0000000000
    ho provato a fare un cast a long double magari si vedeva qualcosa, ma:

    codice:
    #include <stdio.h>
    #include <math.h>
    
    int main()
    {
       printf("%.10Lf\n", (long double)exp(50));
    
       return 0;
    }
    ritorna:

    codice:
    warning: unknown conversion type character 'L' in format

    ????

  10. #10
    Ho provato con VC++ su Windows e effettivamente mi dà la versione con gli zeri; un'altra possibilità che mi viene in mente è che nella versione con gli zeri venga usato un normale double a 8 byte, mentre nell'altro, tramite qualche ottimizzazione, possa essere usato direttamente il valore a 80 bit dei registri della FPU (ma non sono assicuramente sicuro di ciò); un'altra possibilità potrebbe essere che la funzione exp da una parte sia più precisa che dall'altra, ma mi pare improbabile.
    Amaro C++, il gusto pieno dell'undefined behavior.

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 © 2025 vBulletin Solutions, Inc. All rights reserved.