1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| function readDouble()
{
// 32 bits
//$val = 0xBF866666 ; // -1.05
//$val = 0xC1199999 ; //-9.6
//$val = 0x3EC00000 ; // 0.375
$val = readUInt64() ;
/* 64 bits */
// S0eeeeeeeeeeMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
$sizeOfMantisse = 52 ;
$signMask = 1 << 63 ; //
$exposantMask = 0x7FF << $sizeOfMantisse ; // eeeeeeeeeee
$mantisseMask = 0xFFFFFFFFFFFFF ; // MM...MM
$biais = 1023 ;
/* 32 bits
$sizeOfMantisse = 23 ;
$signMask = 1 << 31 ; // 0x80000000
$exposantMask = 0xFF << $sizeOfMantisse ; // eeeeeeeeee 0x7F800000
$mantisseMask = 0x7FFFFF ; // MM...MM
$biais = 127 ;
*/
/* 80 bits
$sizeOfMantisse = 64 ;
$signMask = 1 << 79 ;
$exposantMask = 0x7FFF<< $sizeOfMantisse ; // ee...ee
$mantisseMask = 0xFFFFFFFFFFFFFFFF ; // MM...MM
$biais = 16383 ;
*/
$sign = (($val & $signMask) != 0) ;
$exposant = ($val & $exposantMask) >> $sizeOfMantisse ;
$tmpMantisse = $val & $mantisseMask ;
$div = 1 ;
$mantisse = 1 ;
for($i = 0; $i < $sizeOfMantisse; $i++)
{
$bit = ($tmpMantisse >> ($sizeOfMantisse - $i)) & 1 ;
$mantisse += ((1 / $div) * $bit) ;
$div = $div * 2 ;
}
if (($exposant == 0) && ($mantisse == 0))
{
$number = 0.0 / 1.0 ;
}
else
{
$number = pow(2, $exposant - $biais) * $mantisse ;
if ($sign)
{
$number = -1 * $number ;
}
}
return $number ;
} |
Partager