note 102126 modified in language.types.float by tyrael
| From: | tyrael@php.net | Date: | Sun, 22 Jul 2012 22:52:16 +0000 |
| Subject: | note 102126 modified in language.types.float by tyrael | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-189359@lists.php.net to get a copy of this message | ||
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	 &
#9;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; } /** Using either function will
return a value which can be used on the other function * to return the original
input. (Hope it helps =) **/
?> Second function
(HEX2FLOAT32n) converts Hexadecimal 8 digit strings to fixed decimals float numbers.
(complementary to FLOAT2HEX32n above)
<?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. * **/
/** HEX2FLOAT32n * (Convert 8 digit
hexadecimal values to fixed decimals float numbers (single-precision 32bits) *
Accepts 8 digit hexadecimal values on a string (i.e.- F1A9B02C) and single integer to fix number of
decimals * @usage: *
hex2float32n("c9be2c49",2); returns -> "-1557897.13"
**/ function hex2float32n($number,$nd) {
//Separate each hexadecimal digit for ($i=0;
$i<strlen($number); $i++) { $hex[]=substr($number,$i,1);
} //Convert each hexadecimal digit to integer
for ($i=0; $i<count($hex); $i++) {
$dec[]=hexdec($hex[$i]); } //Convert each decimal value to
4bit binary and join on a string for ($i=0; $i<count($dec); $i++) {
$binfinal.=sprintf("%04d",decbin($dec[$i]));
} //Get sign 1bit value
$sign=substr($binfinal,0,1); //Get exponent 8bit value
$exp=substr($binfinal,1,8); //Get mantissa 23bit value
$mantissa=substr($binfinal,9); //Convert & adjunt binary exponent to
integer $exp=bindec($exp); $exp-=127;
//Assign mantissa to pre-scientific binary notation $scibin=$mantissa;
//Split $scibin into integral & fraction parts through exponent
$binint=substr($scibin,0,$exp);
$binpoint=substr($scibin,$exp); //Convert integral binary part to decimal
integer $intnumber=bindec("1".$binint);
//Split each binary fractional digit for ($i=0; $i<strlen($binpoint);
$i++) { $tmppoin
t[]=substr($binpoint,$i,1); } //Reverse order to work
backwards $tmppoint=array_reverse($tmppoint); //Convert
base 2 digits to decimal
$tpointnumber=number_format($tmppoint[0]/2,strlen($binpoint),'.','');
for ($i=1; $i<strlen($binpoint); $i++) {
$pointnumber=number_format($tpointnumber/2,strlen($binpoint),'.','');
$tpointnumber=$tmppoint[$i+1].substr($pointnumber,1);
} //Join both decimal section to get final number
$floatfinal=$intnumber+$pointnumber; //Convert to positive or negative based on
binary sign bit if ($sign==1) { $floatfinal=-$floatfinal; }
//Format float number to fixed decimals required return
number_format($floatfinal,$nd,'.','');
} /** Using either function will return a
value which can be used on the other function * to return the original input.
(Hope it helps =) **/ ?>
--was--
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;
}
/** Using either function will return a value which can be used on the other function
* to return the original input. (Hope it helps =)
**/
?>
Second function (HEX2FLOAT32n) converts Hexadecimal 8 digit strings to fixed decimals float numbers.
(complementary to FLOAT2HEX32n above)
<?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.
*
**/
/** HEX2FLOAT32n
* (Convert 8 digit hexadecimal values to fixed decimals float numbers (single-precision 32bits)
* Accepts 8 digit hexadecimal values on a string (i.e.- F1A9B02C) and single integer to fix number
of decimals
* @usage:
* hex2float32n("c9be2c49",2); returns -> "-1557897.13"
**/
function hex2float32n($number,$nd) {
//Separate each hexadecimal digit
for ($i=0; $i<strlen($number); $i++) {
$hex[]=substr($number,$i,1);
}
//Convert each hexadecimal digit to integer
for ($i=0; $i<count($hex); $i++) {
$dec[]=hexdec($hex[$i]);
}
//Convert each decimal value to 4bit binary and join on a string
for ($i=0; $i<count($dec); $i++) {
$binfinal.=sprintf("%04d",decbin($dec[$i]));
}
//Get sign 1bit value
$sign=substr($binfinal,0,1);
//Get exponent 8bit value
$exp=substr($binfinal,1,8);
//Get mantissa 23bit value
$mantissa=substr($binfinal,9);
//Convert & adjunt binary exponent to integer
$exp=bindec($exp);
$exp-=127;
//Assign mantissa to pre-scientific binary notation
$scibin=$mantissa;
//Split $scibin into integral & fraction parts through exponent
$binint=substr($scibin,0,$exp);
$binpoint=substr($scibin,$exp);
//Convert integral binary part to decimal integer
$intnumber=bindec("1".$binint);
//Split each binary fractional digit
for ($i=0; $i<strlen($binpoint); $i++) {
$tmppoint[]=substr($binpoint,$i,1);
}
//Reverse order to work backwards
$tmppoint=array_reverse($tmppoint);
//Convert base 2 digits to decimal
$tpointnumber=number_format($tmppoint[0]/2,strlen($binpoint),'.','');
for ($i=1; $i<strlen($binpoint); $i++) {
$pointnumber=number_format($tpointnumber/2,strlen($binpoint),'.','');
$tpointnumber=$tmppoint[$i+1].substr($pointnumber,1);
}
//Join both decimal section to get final number
$floatfinal=$intnumber+$pointnumber;
//Convert to positive or negative based on binary sign bit
if ($sign==1) { $floatfinal=-$floatfinal; }
//Format float number to fixed decimals required
return number_format($floatfinal,$nd,'.','');
}
/** Using either function will return a value which can be used on the other function
* to return the original input. (Hope it helps =)
**/
?>
http://php.net/manual/en/language.types.float.php