note 111348 deleted from language.types.float by danbrown
| From: | danbrown@php.net | Date: | Tue, 05 Mar 2013 16:08:47 +0000 |
| Subject: | note 111348 deleted from language.types.float by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-193919@lists.php.net to get a copy of this message | ||
Note Submitter: info at nstiac dot com
----
There are many scripts/functions to convert a Hex string to a Floating point number, but i
could'nt find any usable function to convert a float2hex (float number to hexadecimal) .. so i
went on an made one! .. to my surprise.. it didn't matched the other existing functions results
exactly due to different methods used on each .. so i went on an created a complementary function to
have both results match float2hex32n<->hex2float32n.
<?php
/** Complementary functions to CONVERT PHP FLOATING POINT NUMBERS or DECIMALS
* (IEEE 754 single-precision 32 bit) TO HEXADECIMAL AND BACK.
*
* @author NSTIAC (Jorge D. Baigorri Salas) http://www.nstiac.com http://www.n2works.com
* @created on 28/Jan/2010 / time spent: 2hours approx.
* @special thanks to Thomas Finley's article "Floating Point"
* http://tfinley.net/notes/cps104/floating.html
*
* These functions allow to convert any php floating point numbers with the
* notation 1.234 (or fixed point numbers) into their corresponding 8 digits
* hexadecimal notation. (i.e.- 1557897.40 -> 49BE2C4B <- 1557897.40) by
* disregarding their implicit format and treating them at will as either
* integer, decimals, binary numbers, hexadecimal values, or plain text.
*
**/
/** FLOAT2HEX32n
* (Convert php float numbers or decimals (single-precision 32bits) to 8 digit Hexadecimal)
* Accepts only fixed point notation decimal numbers or fractions on a string (i.e.-
"1.23456")
* @usage:
* float2hex32n("-1557897.13"); returns "c9be2c49"
**/
function float2hex32n($number) {
//Convert non-decimal to decimal.
$number=number_format($number,23,'.','');
//Get the integer portion of $number
if ($number>0) {
$intnumber=substr($number,0,strpos($number,"."));
} else {
//Check whether is a negative number to remove - sign.
$intnumber=substr($number,1,strpos($number,"."));
}
//Convert integer to binary
$binint=decbin($intnumber);
//Get the decimal fraction of the number
$pointnumber=substr($number,strpos($number,"."));
//Add a 0 to treat as single decimal fraction
$pointnumber="0".$pointnumber;
//Convert decimal values to base 2
$tmppoint=number_format($pointnumber*2,23,'.','');
for ($i=0; $i<23; $i++) {
$binpoint.=substr((string)$tmppoint,0,1);
$tmppoint=substr((string)$tmppoint,1);
$tmppoint=number_format($tmppoint*2,23,'.','');
}
//Gather both values to get base 2 binary fraction
$scibin=$binint.".".$binpoint;
//Find fraction separator "." position
$exp=strpos($scibin,".");
//Transform to scientific notation (1.x^exp)
$scibin=substr($binint,0,1).".".substr($binint,1).$binpoint;
//Create mantissa
if ($scibin>1) {
$mantissa=substr($scibin,2);
} else {
$mantissa=substr($scibin,1);
}
//Fill mantissa to 23 bit value
$fill23=23-strlen($mantissa);
for ($i=0; $i<$fill23; $i++) {
$mantissa.="0";
}
//Convert fraction separator position to exponent value
if ($exp>0) { $exp--; }
//Adjust to binary notation exponent value
$exp+=127;
//Convert to 8 bit binary
$exp=decbin($exp);
//Find 1 bit sign value
if ($number>0) { $sign=0; } else { $sign=1; }
//Compose final binary value
$binfinal=$sign.$exp.$mantissa;
//Reorganizae number into 4digit/bits packets and
//finally convert to decimal value and to hex.
$hexfinal.=dechex(bindec(substr($binfinal,0,4)));
$hexfinal.=dechex(bindec(substr($binfinal,4,4)));
$hexfinal.=dechex(bindec(substr($binfinal,8,4)));
$hexfinal.=dechex(bindec(substr($binfinal,12,4)));
$hexfinal.=dechex(bindec(substr($binfinal,16,4)));
$hexfinal.=dechex(bindec(substr($binfinal,20,4)));
$hexfinal.=dechex(bindec(substr($binfinal,24,4)));
$hexfinal.=dechex(bindec(substr($binfinal,28,4)));
return $hexfinal;
}
?>