note 87727 modified in function.dechex by danbrown

From: Date: Thu, 18 Dec 2008 14:45:08 +0000
Subject: note 87727 modified in function.dechex by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-148314@lists.php.net to get a copy of this message
Because none of the previous comments worked for me, I made a simple function that converts signed decimal numbers to hexadecimal strings using an implementation of Two's completement (http://en.wikipedia.org/wiki/Two%27s_complement) and BCMath so it can handle numbers virtually as big as you want. Optionnally, you can set a number of digits if you need padding added. <?php function dec2hex($dec, $digits=false) { $hex = ''; $sign = $dec < 0 ? false : true; // Converts the decimal number into hexadecimal ignoring the sign for now. while ($dec) { // Calculates the modulus, converts it to hexadecimal and adds it to the result. $hex .= dechex(abs(bcmod($dec, '16'))); // Divises the decimal number by 16 and loop. $dec = bcdiv($dec, '16', 0); } // Adds some padding to get the required number of digits if specified. if ($digits) { while (strlen($hex) < $digits) { $hex .= '0'; } } // If the decimal number was positive, we're done. if ($sign) { // The result has to be reversed because of the way it was computed. return strrev($hex); } // The decimal number was negative so first we need to flip each digit individually. for ($i = 0; isset($hex[$i]); $i++) { $hex[$i] = dechex(15 - hexdec($hex[$i])); } // Now we need to add 1 to the result. // This handles the carry so 'f' becomes '0' until we reach a digit that isn't 'f'. for ($i = 0; isset($hex[$i]) && $hex[$i] == 'f'; $i++) { $hex[$i] = '0'; } // Finally unless all the digits were f's, we add one to the latest digit that wasn't. if (isset($hex[$i])) { $hex[$i] = dechex(hexdec($hex[$i]) + 1); } // All done! Again, we need to reverse the result. return strrev($hex); } ?> Now if you try it with 2 digits hexadecimal numbers, you'll see that dec2hex(255) is FF and dec2hex(-255) is 01. As expected: 0xFF + 0x01 = 0x00 --was-- Because none of the previous comments worked for me, I made a simple function that converts signed decimal numbers to hexadecimal strings using an implementation of Two's completement (http://en.wikipedia.org/wiki/Two%27s_complement) and BCMath so it can handle numbers virtually as big as you want. Optionnally, you can set a number of digits if you need padding added. <?php function dec2hex($dec, $digits=false) { $hex = ''; $sign = $dec < 0 ? false : true; // Converts the decimal number into hexadecimal ignoring the sign for now. while ($dec) { // Calculates the modulus, converts it to hexadecimal and adds it to the result. $hex .= dechex(abs(bcmod($dec, '16'))); // Divises the decimal number by 16 and loop. $dec = bcdiv($dec, '16', 0); } // Adds some padding to get the required number of digits if specified. if ($digits) { while (strlen($hex) < $digits) { $hex .= '0'; } } // If the decimal number was positive, we're done. if ($sign) { // The result has to be reversed because of the way it was computed. return strrev($hex); } // The decimal number was negative so first we need to flip each digit individually. for ($i = 0; isset($hex[$i]); $i++) { $hex[$i] = dechex(15 - hexdec($hex[$i])); } // Now we need to add 1 to the result. // This handles the carry so 'f' becomes '0' until we reach a digit that isn't 'f'. for ($i = 0; isset($hex[$i]) && $hex[$i] == 'f'; $i++) { $hex[$i] = '0'; } // Finally unless all the digits were f's, we add one to the latest digit that wasn't. if (isset($hex[$i])) { $hex[$i] = dechex(hexdec($hex[$i]) + 1); } // All done! Again, we need to reverse the result. return strrev($hex); } ?> Now if you try it with 2 digits hexadecimal numbers, you'll see that dec2hex(255) is FF and dec2hex(-255) is 01. As expected: 0xFF + 0x01 = 0x00 PS: The function in my previous note just under this one (#87702) doesn't actually work properly. If someone could just delete it, that'd be cool. Sorry about that. http://php.net/manual/en/function.dechex.php

« previous php.notes (#148314) next »