2009-07-15 3 views

risposta

1

Per interpretarlo in realtà probabilmente non si vorrebbe trattarlo come byte in ogni caso perché i limiti di mantisa non si allineano a un intervallo di 8 bit.

Qualcosa sulla falsariga di:

mantisa = (*(unsigned int *)&floatVal) | MANTISA_MASK; 
exp  = ((*(unsigned int *)&floatVal) | EXP_MASK ) >> EXP_SHIFT; 
sign = ((*(unsigned int *)&floatVal) | SIGN_MASK ) >> SIGN_SHIFT; 

lasceremmo metto da parte per giocare con il centro succo.

EDIT:

#include <stdio.h> 

    void main() 
    { 
    float a = 4; 
    unsigned int exp,sign,mantisa; 
    int i; 

     for(i = 0;i<4;i++) 
     { 
      exp  = (*((unsigned int *)&a) >>23) & 0xFF; 
      sign  = (*((unsigned int *)&a) >>31) & 0x01; 
      mantisa = (*((unsigned int *)&a)) & 0x7FFFFF | 0x800000; 

      printf("a  = %04x\r\n",*((unsigned int *)&a)); 
      printf("a  = %f\r\n",a); 
      printf("exp  = %i, %02x\r\n",exp,exp); 
      printf("sign = %i, %02x\r\n",sign,sign); 
      printf("mantisa = %i, %02x\r\n\r\n",mantisa,mantisa); 
      a = -a/2; 

     } 
    } 

produce:

a  = 40800000 
    a  = 4.000000 
    exp  = 129, 81 
    sign = 0, 00 
    mantisa = 8388608, 800000 

    a  = c0000000 
    a  = -2.000000 
    exp  = 128, 80 
    sign = 1, 01 
    mantisa = 8388608, 800000 

    a  = 3f800000 
    a  = 1.000000 
    exp  = 127, 7f 
    sign = 0, 00 
    mantisa = 8388608, 800000 

    a  = bf000000 
    a  = -0.500000 
    exp  = 126, 7e 
    sign = 1, 01 
    mantisa = 8388608, 800000 

    Press any key to continue . . . 
+0

Sì, ma questo comportamento non è definito (accesso a un valore float utilizzando un puntatore int). Hai la certezza di poter accedere ai byte di un oggetto come una matrice di caratteri non firmati (in C, almeno - Non sono sicuro della dicitura paragonabile nello standard C++), ma non come altri tipi di dati, in generale . In particolare, l'ottimizzatore del compilatore ha il diritto di presumere di non averlo fatto e di applicare ottimizzazioni che possono infrangere il codice se ne hai. – dewtell

+1

Inoltre, dovresti prendere l'indirizzo di floatVal prima di lanciarlo comunque su un altro tipo di puntatore. Un esempio di ciò che stavo dicendo sull'ottimizzatore: se il compilatore manteneva il valore corrente di floatVal in un registro, l'ottimizzatore avrebbe il diritto di presumere che non aveva bisogno di versare il valore corrente in memoria prima di eseguire questo codice, poiché quei puntatori int non possono accedere legalmente al valore float. Quindi, anche se il comportamento indefinito non ha fatto esplodere il tuo computer, potresti facilmente raccogliere la spazzatura casuale piuttosto che l'ultimo valore di floatVal con questo codice. – dewtell

+0

Funziona su big e little endian. – NoMoreZealots

14

Prova questo link: http://en.wikipedia.org/wiki/IEEE_754

Ho appena scoperto che questo potrebbe essere un po 'più utile: http://en.wikipedia.org/wiki/IEEE_754-1985

Questa è l'IEEE-standard per i numeri in virgola mobile. Ce n'è una dal 1985 e una edizione riveduta del 2008. Float è a 32 bit, il doppio a 64 bit (spiegato nel secondo link).


Edit: Thx per il commento di Don, ecco il link per Intels descrizione 80bit in virgola mobile: http://en.wikipedia.org/wiki/Extended_precision

+3

mi piacerebbe aggiungere che questo è il caso schiacciante comune, ma che la scelta è influenzata dal hardware. –

3

Potrebbe anche essere la pena di notare che v'è un membro static bool const di std::numeric_limits, is_iec559, che è naturalmente disponibile solo per i tipi a virgola mobile. Il nome è piuttosto auto esplicativo ...

+2

Autoesplicativo purché si sappia che IEC 559 è il nome della rinormalizzazione per ISO di ciò che è meglio conosciuto come IEEE 754. E si dovrebbe anche sapere che potrebbe esserci un falso negativo: quello standard è più di una rappresentazione - - In realtà, non sono sicuro che la versione del 1985 imponga una rappresentazione - ma anche un comportamento (arrotondamenti, denormali, ...). Impostare quel membro su true implica che obbedisci a tutto ciò e che è difficile su qualche piattaforma. Per quanto ne so, le prime versioni di Java l'hanno imposto e poi sono tornate indietro, dato che il rendimento era troppo alto. – AProgrammer