Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    Standard IEEE su Nan e Inf

    Ho la necessità di rappresentare infinito e forma indeterminata, in dei float, in primo luogo ho pensato di utilizzare rispettivamente il massimo e il minimo, numero float rappresentabile nella mia macchina. Ma cosi facendo avrei dovuto fare io i controlli sulle divisioni per vedere se il quoziente è reale, infinito, nullo oppure indeterminato. Allora frugando un po qua e la, e facendo alcuni esperimenti con il codice; scopro che lo standard IEEE che regola la codifica binaria dei numeri in virgola mobile, ha già definito i valori inf e Nan( not a number ) ossia forma indeterminata. L'infinito "inf" è codificato ponendo tutti i bit dell'esponente a 1 e tutti quelli della mantissa a zero, mentre "Nan" ha l'esponente sempre tutto a 1 e la mantissa diversa da 0.
    Il bello di ciò è che, se noi facciamo ad'esempio 4/0 e poi stampiamo l'ambiente ci restituisce inf oppure ci restituisce nan se facciamo 0/0. Questi test li ho fatti nel laboratorio della mia facoltà, sotto ubuntu 8.10.
    Ho provato a emulare gli esperimenti fatti in laboratorio con il mio pc sotto ubuntu 12.10; pero anziché rispondermi con le preziose informazioni che ormai m'aspettavo, l'ambiente a real time mi dice esclusivamente "Eccezione in virgola mobile" sia che si trati di inf, che di nan.

    Qualche suggerimento?

  2. #2
    Supponendo che tu stia programmando in C (cosa che dovresti specificare), lo standard non impone l'uso di IEEE 754 per i numeri in virgola mobile, per cui è possibile che il tuo ambiente target usi un sistema di numeri in virgola mobile che non supporta i vari NaN e Inf.
    In ogni caso, dovresti specificare l'"ambiente real time" esattamente che cos'è (piattaforma, sistema operativo, ...), in modo che ti si possano dare consigli mirati.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Si scrivo in c, ed' intendevo ambiente a run time! Comunque ho risolto. Non avevo pensato al fatto che l'operatore " / ", in c è sovraccaricato, cosi che sia possibile float/float=float , int/int=int e int/int=float. Per le frazioni eterogenee tipo int/float penso che il compilatore esegua un cast implicito in questo modo (float)int / float.
    Naturalmente essendo inf e nan, codificati in dei float, la divisione int/int=int non potrà mai restituire uno di questi risultati, ecco perché viene generata un'eccezione in virgola mobile ed il programma restituisce il controllo all'OS prematuramente.

    Per concretizzare, in laboratorio scrissi:
    codice:
    printf("\t%f", 0.0/0.0);
    Mentre a casa:
    codice:
    printf("\t%f", 0/0);
    Per correggere:
    codice:
    printf("\t%f", (float) 0/0);
    Alcuni casi che generano eccezioni:
    codice:
    #include<stdio.h>
    #include<math.h>
    
    int main()		
    {	
    
    	float inf = (float) 1/0;
    	
    	printf("1\t%f\n", -inf );
    	printf("2\t%f\n", 1/inf );
    	printf("3\t%f\n", 0.0/0.0 );
    	printf("4\t%f\n", inf/inf );
    	printf("5\t%f\n", inf-inf );
    	printf("6\t%f\n", inf+inf );
    	printf("7\t%f\n", inf*inf );
    	printf("8\t%f\n", pow(inf , 2) );
    	printf("9\t%f\n", sqrt(-1) );
    	printf("10\t%f\n", sqrt(inf) );
    	
    	return 0; 
    }
    Ed'ecco i rispettivi output:
    codice:
    dante@dante-PC:~/Documenti/c/Matematica$ ./limiti
    1       -inf
    2       0.000000
    3       -nan
    4       -nan
    5       -nan
    6       -inf
    7       inf
    8       inf
    9       -nan
    10      -nan
    Come vediamo questi oggetti sono estremamente maneggevoli possiamo passare da +inf a -inf semplicemente anteponendo il segno non sono due oggetti distinti. Ciò è ragionevole dal momento che nello standard IEEE v'è un bit della stringa (il più significativo) dedicato al segno, dal momento che la codifica di inf e nan utilizza esclusivamente i bit dedicati alla mantissa e all'esponente; il flag di segno rimane disponibile per il suo scopo.

  4. #4
    Utente di HTML.it
    Registrato dal
    Dec 2006
    Messaggi
    156
    Ciao,
    giusto una precisazione se stiamo parlando di C e non di C++:

    Originariamente inviato da pistilloi
    Non avevo pensato al fatto che l'operatore " / ", in c è sovraccaricato, cosi che sia possibile float/float=float , int/int=int e int/int=float.
    In C non esiste il concetto di overloading, quindi non è corretto dire che "/" è sovraccaricato.
    Non è neanche possibile fare int/int=float a meno di non castare a float uno dei due argomenti.

    Ciao

  5. #5
    In c il programmatore(utente) non può sovraccaricare gli operatori, ma di fatto tutti gli operatori predefiniti sono sovraccarichi, altrimenti non si spiega perché sia possibile fare: float+float=float e int+int=int; due operazioni evidentemente differenti che vengono chiamate entrambe con il simbolo " + ", naturalmente il compilatore in base agli argomenti esegue la somma tra reali o quella tra interi, senza ambiguità.
    Per quanto riguarda int/int=float hai ragione, l'operatore binario "/" se ha come parametri due interi restituisce un'intero. E ciò è in perfetto accordo con la soluzione del problema che ho proposto.
    Infatti 0/0=intero, se vogliamo la forma indeterminata NaN dobbiamo convertirlo esplicitamente in un float, quindi:
    0/0 (float) = float = nan.

  6. #6
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613
    Se non è un problema insormontabile dal punto di vista delle prestazioni, sarebbe meglio controllare manualmente i valori prima della divisione. Il tuo programma così non è portabile come ti è già stato segnalato, e ad essere pignoli è anche errato visto che la divisione per zero in C è undefined behavior.

    Originariamente inviato da pistilloi
    Infatti 0/0=intero, se vogliamo la forma indeterminata NaN dobbiamo convertirlo esplicitamente in un float, quindi:
    0/0 (float) = float = nan.
    Non so bene cosa intendessi visto la strana posizione del cast, ma ciò che va castato è un operando, non il risultato.

  7. #7

    Non fermiamoci sulle sottigliezze, comunque sto lavorando ad'un programma che calcoli il limite di una funzione, i calcoli in virgola mobile vengono eseguiti via hardware dalla fpu, l'ambiente può essere informato del fatto che io debba eseguire operazioni del genere grazie a queste librerie: http://linux.die.net/man/3/feenableexcept , http://linux.die.net/man/3/fedisableexcept ; cosi da non interrompere l'esecuzione, con la segnalazione di eccezioni in virgola mobile. Ed ecco risolto il problema della portabilità. Inoltre il programma non è scorretto perché come da titolo, i valori inf e nan sono specificati nello standard IEEE quello su cui si basano li elettronici per costruire le unità di calcolo in virgola mobile. Quindi la possibilità di eseguire operazioni del genere è nativa della macchina.

  8. #8
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613
    Originariamente inviato da pistilloi

    Non fermiamoci sulle sottigliezze, comunque sto lavorando ad'un programma che calcoli il limite di una funzione, i calcoli in virgola mobile vengono eseguiti via hardware dalla fpu, l'ambiente può essere informato del fatto che io debba eseguire operazioni del genere grazie a queste librerie: http://linux.die.net/man/3/feenableexcept , http://linux.die.net/man/3/fedisableexcept ; cosi da non interrompere l'esecuzione, con la segnalazione di eccezioni in virgola mobile. Ed ecco risolto il problema della portabilità. Inoltre il programma non è scorretto perché come da titolo, i valori inf e nan sono specificati nello standard IEEE quello su cui si basano li elettronici per costruire le unità di calcolo in virgola mobile. Quindi la possibilità di eseguire operazioni del genere è nativa della macchina.
    Non capisco che c'entrino gli aspetti hardware dal punto di vista della portabilità, stai scrivendo codice C e la portabilità è definita dallo standard C. Le librerie che hai linkato NON sono standard, o almeno non del tutto (in alcuni punti c'è anche scritto...), e MItaly ti ha già fatto notare che C non impone l'utilizzo di quello standard IEEE. Citando lo standard:

    The result of the / operator is the quotient from the division of the first operand by the second; the result of the % operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined.
    Comunque basta mettersi d'accordo su ciò di cui si vuole parlare, mica è obbligatorio scrivere un programma conforme allo standard e completamente portabile, può non interessare, io ho solo fatto la mia proposta (che per carità può pure essere completamente sbagliata). Oppure può non essere accettabile per te fare quei test, dal punto di vista delle prestazioni.
    Però se nella stessa frase mi parli di portabilità e poi di dettagli implementativi hardware, beh... forse stiamo parlando di cose diverse.

  9. #9
    Originariamente inviato da Kaamos
    MItaly ti ha già fatto notare che C non impone l'utilizzo di quello standard IEEE.
    Occhio però... non lo impone, ma (1) è ubiquitario, e (2) è esplicitamente supportata come parte "opzionale" dello standard: se guardi nello standard C99, Annex F è spiegato come i tipi in virgola mobile del C vengono a corrispondere ai tipi dell'IEEE 754 (ora IEC 60559) e come i vari Inf/NaN & co. vengono creati/interagiscono con i vari operatori e funzioni di libreria.
    Per questo motivo, a meno di non lavorare su piattaforme estremamente "strane", l'uso dei tipi in floating point del C aspettandosi che si comportino come da IEEE 754 è "sostanzialmente" portabile.
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613
    Originariamente inviato da MItaly
    Occhio però... non lo impone, ma (1) è ubiquitario, e (2) è esplicitamente supportata come parte "opzionale" dello standard: se guardi nello standard C99, Annex F è spiegato come i tipi in virgola mobile del C vengono a corrispondere ai tipi dell'IEEE 754 (ora IEC 60559) e come i vari Inf/NaN & co. vengono creati/interagiscono con i vari operatori e funzioni di libreria.
    Per questo motivo, a meno di non lavorare su piattaforme estremamente "strane", l'uso dei tipi in floating point del C aspettandosi che si comportino come da IEEE 754 è "sostanzialmente" portabile.
    Si gli ho dato un'occhiata prima di postare, ma sostanzialmente il discorso penso sia sempre quello che ho detto nel mio primo post... se non è il collo di bottiglia dell'applicazione, tutta questa discussione secondo me ha poco senso. Comunque grazie della precisazione, già che ci sono approfondirò un po' l'appendice.

    EDIT: comunque sarebbero potuti essere più precisi riguardo alle moltiplicazioni/divisioni, è contro-intuitivo specificare undefined behavior in un posto e poi mettere un "però" in un'altra parte del documento!

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