note 102126 modified in language.types.float by tyrael

From: 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&#39;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&#39;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&#60;-&#62;hex2float32n.&#13;&#10;&#13;&#10;&#60;?php&#13;&#10;&#13;&#10;/** Complementary functions to CONVERT PHP FLOATING POINT NUMBERS or DECIMALS&#13;&#10; * (IEEE 754 single-precision 32 bit) TO HEXADECIMAL AND BACK.&#13;&#10; *&#9;&#13;&#10; * @author NSTIAC (Jorge D. Baigorri Salas) http://www.nstiac.com http://www.n2works.com&#13;&#10; * @created on 28/Jan/2010 / time spent: 2hours approx.&#13;&#10; * @special thanks to Thomas Finley&#39;s article &#34;Floating Point&#34; &#13;&#10; * http://tfinley.net/notes/cps104/floating.html&#13;&#10; *&#13;&#10; * These functions allow to convert any php floating point numbers with the &#13;&#10; * notation 1.234 (or fixed point numbers) into their corresponding 8 digits&#13;&#10; * hexadecimal notation. (i.e.- 1557897.40 -&#62; 49BE2C4B &#60;- 1557897.40) by&#13;&#10; * disregarding their implicit format and treating them at will as either&#13;&#10; * integer, decimals, binary numbers, hexadecimal values, or plain text.&#13;&#10; *&#9;&#9;&#13;&#10;**/&#13;&#10;&#13;&#10;/** FLOAT2HEX32n &#13;&#10; * (Convert php float numbers or decimals (single-precision 32bits) to 8 digit Hexadecimal)&#13;&#10; * Accepts only fixed point notation decimal numbers or fractions on a string (i.e.- &#34;1.23456&#34;)&#13;&#10; * @usage:&#13;&#10; * float2hex32n(&#34;-1557897.13&#34;); returns &#34;c9be2c49&#34;&#13;&#10;**/&#13;&#10;&#13;&#10;function float2hex32n($number) {&#13;&#10;&#9;//Convert non-decimal to decimal.&#13;&#10;&#9;$number=number_format($number,23,&#39;.&#39;,&#39;&#39;);&#13;&#10;&#9;//Get the integer portion of $number&#9;&#13;&#10;&#9;if ($number&#62;0) {&#13;&#10;&#9;&#9;$intnumber=substr($number,0,strpos($number,&#34;.&#34;));&#13;&#10;&#9;} else {&#13;&#10;&#9;&#9;//Check whether is a negative number to remove - sign.&#13;&#10;&#9;&#9;$intnumber=substr($number,1,strpos($number,&#34;.&#34;));&#13;&#10;&#9;}&#13;&#10;&#9;//Convert integer to binary&#13;&#10;&#9;$binint=decbin($intnumber);&#13;&#10;&#9;//Get the decimal fraction of the number&#13;&#10;&#9;$pointnumber=substr($number,strpos($number,&#34;.&#34;));&#13;&#10;&#9;//Add a 0 to treat as single decimal fraction&#13;&#10;&#9;$pointnumber=&#34;0&#34;.$pointnumber;&#13;&#10;&#9;//Convert decimal values to base 2&#13;&#10;&#9;$tmppoint=number_format($pointnumber*2,23,&#39;.&#39;,&#39;&#39;);&#13;&#10;&#9;for ($i=0; $i&#60;23; $i++) {&#13;&#10;&#9;&#9;$binpoint.=substr((string)$tmppoint,0,1);&#13;&#10;&#9;&#9;$tmppoint=substr((string)$tmppoint,1);&#13;&#10;&#9;&#9;$tmppoint=number_format($tmppoint*2,23,&#39;.&#39;,&#39;&#39;);&#13;&#10;&#9;}&#13;&#10;&#9;//Gather both values to get base 2 binary fraction&#13;&#10;&#9;$scibin=$binint.&#34;.&#34;.$binpoint;&#13;&#10;&#9;//Find fraction separator &#34;.&#34; position&#13;&#10;&#9;$exp=strpos($scibin,&#34;.&#34;);&#13;&#10;&#9;//Transform to scientific notation (1.x^exp)&#13;&#10;&#9;$scibin=substr($binint,0,1).&#34;.&#34;.substr($binint,1).$binpoint;&#13;&#10;&#9;//Create mantissa&#13;&#10;&#9;if ($scibin&#62;1) {&#13;&#10;&#9;&#9;$mantissa=substr($scibin,2);&#13;&#10;&#9;} else { &#13;&#10;&#9;&#9;$mantissa=substr($scibin,1);&#13;&#10;&#9;}&#13;&#10;&#9;//Fill mantissa to 23 bit value&#13;&#10;&#9;$fill23=23-strlen($mantissa);&#13;&#10;&#9;for ($i=0; $i&#60;$fill23; $i++) {&#13;&#10;&#9;$mantissa.=&#34;0&#34;;&#13;&#10;&#9;}&#13;&#10;&#9;//Convert fraction separator position to exponent value&#13;&#10;&#9;if ($exp&#62;0) { $exp--; }&#13;&#10;&#9;//Adjust to binary notation exponent value&#13;&#10;&#9;$exp+=127;&#13;&#10;&#9;//Convert to 8 bit binary&#13;&#10;&#9;$exp=decbin($exp);&#13;&#10;&#9;//Find 1 bit sign value&#9;&#13;&#10;& #9;if ($number&#62;0) { $sign=0; } else { $sign=1; } &#13;&#10;&#9;//Compose final binary value&#13;&#10;&#9;$binfinal=$sign.$exp.$mantissa;&#13;&#10;&#9;//Reorganizae number into 4digit/bits packets and&#13;&#10;&#9;//finally convert to decimal value and to hex.&#13;&#10;&#9;$hexfinal.=dechex(bindec(substr($binfinal,0,4)));&#13;&#10;&#9;$hexfinal.=dechex(bindec(substr($binfinal,4,4)));&#13;&#10;&#9;$hexfinal.=dechex(bindec(substr($binfinal,8,4)));&#13;&#10;&#9;$hexfinal.=dechex(bindec(substr($binfinal,12,4)));&#13;&#10;&#9;$hexfinal.=dechex(bindec(substr($binfinal,16,4)));&#13;&#10;&#9;$hexfinal.=dechex(bindec(substr($binfinal,20,4)));&#13;&#10;&#9;$hexfinal.=dechex(bindec(substr($binfinal,24,4)));&#13;&#10;&#9;$hexfinal.=dechex(bindec(substr($binfinal,28,4)));&#13;&#10;&#13;&#10;&#9;return $hexfinal;&#13;&#10;}&#13;&#10;&#13;&#10;/** Using either function will return a value which can be used on the other function&#13;&#10; * to return the original input. (Hope it helps =)&#13;&#10;**/ &#13;&#10;&#13;&#10;?&#62;&#13;&#10;&#13;&#10;Second function (HEX2FLOAT32n) converts Hexadecimal 8 digit strings to fixed decimals float numbers. &#13;&#10;&#13;&#10;(complementary to FLOAT2HEX32n above) &#13;&#10;&#13;&#10;&#60;?php &#13;&#10;&#13;&#10;/** Complementary functions to CONVERT PHP FLOATING POINT NUMBERS or DECIMALS &#13;&#10; * (IEEE 754 single-precision 32 bit) TO HEXADECIMAL AND BACK. &#13;&#10; * &#13;&#10; * @author NSTIAC (Jorge D. Baigorri Salas) http://www.nstiac.com http://www.n2works.com &#13;&#10; * @created on 28/Jan/2010 / time spent: 2hours approx. &#13;&#10; * @special thanks to Thomas Finley&#39;s article &#34;Floating Point&#34; &#13;&#10; * http://tfinley.net/notes/cps104/floating.html &#13;&#10; * &#13;&#10; * These functions allow to convert any php floating point numbers with the &#13;&#10; * notation 1.234 (or fixed point numbers) into their corresponding 8 digits &#13;&#10; * hexadecimal notation. (i.e.- 1557897.40 -&#62; 49BE2C4B &#60;- 1557897.40) by &#13;&#10; * disregarding their implicit format and treating them at will as either &#13;&#10; * integer, decimals, binary numbers, hexadecimal values, or plain text. &#13;&#10; * &#13;&#10;**/ &#13;&#10;&#13;&#10;/** HEX2FLOAT32n &#13;&#10; * (Convert 8 digit hexadecimal values to fixed decimals float numbers (single-precision 32bits) &#13;&#10; * Accepts 8 digit hexadecimal values on a string (i.e.- F1A9B02C) and single integer to fix number of decimals &#13;&#10; * @usage: &#13;&#10; * hex2float32n(&#34;c9be2c49&#34;,2); returns -&#62; &#34;-1557897.13&#34; &#13;&#10;**/ &#13;&#10;&#13;&#10;function hex2float32n($number,$nd) { &#13;&#10; //Separate each hexadecimal digit &#13;&#10; for ($i=0; $i&#60;strlen($number); $i++) { &#13;&#10; $hex[]=substr($number,$i,1); &#13;&#10; } &#13;&#10; //Convert each hexadecimal digit to integer &#13;&#10; for ($i=0; $i&#60;count($hex); $i++) { &#13;&#10; $dec[]=hexdec($hex[$i]); &#13;&#10; } &#13;&#10; //Convert each decimal value to 4bit binary and join on a string &#13;&#10; for ($i=0; $i&#60;count($dec); $i++) { &#13;&#10; $binfinal.=sprintf(&#34;%04d&#34;,decbin($dec[$i])); &#13;&#10; } &#13;&#10; //Get sign 1bit value &#13;&#10; $sign=substr($binfinal,0,1); &#13;&#10; //Get exponent 8bit value &#13;&#10; $exp=substr($binfinal,1,8); &#13;&#10; //Get mantissa 23bit value &#13;&#10; $mantissa=substr($binfinal,9); &#13;&#10; //Convert &#38; adjunt binary exponent to integer &#13;&#10; $exp=bindec($exp); &#13;&#10; $exp-=127; &#13;&#10; //Assign mantissa to pre-scientific binary notation &#13;&#10; $scibin=$mantissa; &#13;&#10; //Split $scibin into integral &#38; fraction parts through exponent &#13;&#10; $binint=substr($scibin,0,$exp); &#13;&#10; $binpoint=substr($scibin,$exp); &#13;&#10; //Convert integral binary part to decimal integer &#13;&#10; $intnumber=bindec(&#34;1&#34;.$binint); &#13;&#10; //Split each binary fractional digit &#13;&#10; for ($i=0; $i&#60;strlen($binpoint); $i++) { &#13;&#10; $tmppoin t[]=substr($binpoint,$i,1); &#13;&#10; } &#13;&#10; //Reverse order to work backwards &#13;&#10; $tmppoint=array_reverse($tmppoint); &#13;&#10; //Convert base 2 digits to decimal &#13;&#10; $tpointnumber=number_format($tmppoint[0]/2,strlen($binpoint),&#39;.&#39;,&#39;&#39;); &#13;&#10; for ($i=1; $i&#60;strlen($binpoint); $i++) { &#13;&#10; $pointnumber=number_format($tpointnumber/2,strlen($binpoint),&#39;.&#39;,&#39;&#39;); &#13;&#10; $tpointnumber=$tmppoint[$i+1].substr($pointnumber,1); &#13;&#10; } &#13;&#10; //Join both decimal section to get final number &#13;&#10; $floatfinal=$intnumber+$pointnumber; &#13;&#10; //Convert to positive or negative based on binary sign bit &#13;&#10; if ($sign==1) { $floatfinal=-$floatfinal; } &#13;&#10; &#13;&#10; //Format float number to fixed decimals required &#13;&#10; return number_format($floatfinal,$nd,&#39;.&#39;,&#39;&#39;); &#13;&#10; &#13;&#10;} &#13;&#10;&#13;&#10;/** Using either function will return a value which can be used on the other function &#13;&#10; * to return the original input. (Hope it helps =) &#13;&#10;**/ &#13;&#10;&#13;&#10;?&#62; --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

« previous php.notes (#189359) next »