Conversione da Binary 32 bit a Float IEEE754 in PHP

bit byte

Non è stato semplice saltarci fuori, per una serie di motivi. La conversione di un numero binario (o esadecimale) ad un numero in virgola mobile non l’avevo mai affrontato perchè in PHP, solitamente, si lavora con numeri “definitivi” (integer, float, ecc). Tale conversione può dipendere da diversi fattori.

Per prima cosa ho dovuto studiarmi un pò lo standard IEEE 754, in particolare i numeri a precisione singola (32 bit). Su Wikipedia è spiegato molto bene il metodo con cui effettuare la trasformazione (esponente, mantissa, ecc). Devo ammettere che prima di trovare il codice “giusto” mi sono imbattuto in diverse librerie che non davano l’esito atteso. Alla fine ho trovato una semplice funzione sul sito PHP nella pagina dedicata al Floating point numbers. Leggendo un po’ di commenti ho trovato l’ottimo intervento di info at forrest79 dot net.

Riporto qui di seguito la funzione completa:

function binToFloat($bin) {
if(strlen($bin) > 32) {
return false;
} else if(strlen($bin) < 32) {
$bin = str_repeat('0', (32 - strlen($bin))) . $bin;
}
$sign = 1;
if(intval($bin[0]) == 1) {
$sign = -1;
}
$binExponent = substr($bin, 1, 8);
$exponent = -127;
for($i = 0; $i < 8; $i++) {
$exponent += (intval($binExponent[7 - $i]) * pow(2, $i));
}
$binBase = substr($bin, 9);
$base = 1.0;
for($x = 0; $x < 23; $x++) {
$base += (intval($binBase[$x]) * pow(0.5, ($x + 1)));
}
$float = (float) $sign * pow(2, $exponent) * $base;
return $float;
}

Per testare il tutto dovreste poter effettuare la seguente conversione:

Bin: 1000011100010111110001111010101
(Bin Corretto: 01000011100010111110001111010101)
Float: 279.77993774414

N.B.: Come potete vedere la funzione aggiunge il primo bit (0) nel caso in cui l’intero binario sia composto da 31 bit e non 32.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *