Why does PHP’s dechex(4000)
not return a signed hexadecimal value?
It returns:
fa0
As opposed to:
0xfa0
And is signed
the correct term to use in describing this problem? Or is there a better term to describe the 0x
portion? Is that called a prefix?
4
This is not about signedness.
fa0
and 0xfa0
represent the exact same number. However, without context, you probably wouldn’t realize that the first represents a number in hexadecimal format. The 0x
prefix is just a hint for you (or the computer) that it represents a hexadecimal number.
As for why it doesn’t: Why should it? It’s not necessary. If you were to process it and already know it represents a hexadecimal number, you would just ignore the 0x
prefix. Thus, it may make processing slightly less cumbersome under some circumstances.
Signedness is about being able to represent both positive and negative values.
7
I can see how you might refer to the 0x
prefix as a “sign”. It signifies that the following digits are hexadecimal. But in programming, we almost universally use the word “sign” to refer to something that indicates whether a number is positive or negative. In a stored numeric value, there’s usually one bit that indicates whether a number is negative. In program text, we can write +42
to denote a positive integer and -42
to denote a negative integer; the +
or -
character is the sign. (I’m glossing over some details regarding 2’s-complement and other representations, and issues regarding 0
; also +
and -
are really operators, not part of the integer constants. Don’t worry about that for now.)
So referring to anything other than a positive-or-negative indicator as a “sign” is bound to cause confusion. The 0x
in a hexadecimal literal like 0xfa0
can sensibly be referred to as a prefix, not as a “sign”.
The name of PHP’s dechex
function, documented here, is actually a bit misleading. It takes an unsigned integer argument and returns a string containing the human-readable hexadecimal representation of that argument. The argument is not decimal; it’s almost certainly stored in binary. We think of integers as decimal because we usually write them that way, but in fact integer values can be written in decimal, octal, hexadecimal, or as complicated expressions — all of which result in a binary stored value. It doesn’t convert decimal to hexadecimal; it converts a number to hexadecimal — a number that may have resulted from the conversion of a decimal literal in the PHP source code to a stored binary integer.
As for why the result of dechex()
doesn’t include the 0x
prefix, the documentation doesn’t say, but it’s probably just because it’s more convenient that way. If you want a string with a 0x
prefix, it’s trivially easy to add it yourself (and to decide whether you want 0x
or 0X
). If dechex()
returned a string with the prefix, and you didn’t want it, you’d have to remove it.
This small program demonstrates these points:
#!/usr/bin/php
<?php
// Various arguments to dechex (decimal, octal, hexadecimal):
echo "dechex(12345678) = "", dechex(12345678), ""n";
echo "dechex(012345678) = "", dechex(012345678), ""n";
echo "dechex(0xDEADBEEF) = "", dechex(0xdeadbeef), ""n";
echo "dechex(4*5) = "", dechex(4*5), ""n";
echo "With a prefix: "0x", dechex(4*5), ""n";
// Another approach using sprintf():
echo sprintf("0x%x", 1234), "n";
// ... or printf:
printf("0X%Xn", 1234);
?>
Here’s the output:
dechex(12345678) = "bc614e"
dechex(012345678) = "53977"
dechex(0xDEADBEEF) = "deadbeef"
dechex(4*5) = "14"
With a prefix: "0x14"
0x4d2
0X4D2
6