Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question
    
dechex() returns unsigned hexadecimal values, that's clearly stated in the manual. What exactly is your question? –  Yannis Rizos Jan 30 '13 at 12:10
3  
You should do some more research on what a signed and unsigned value is exactly. The reason this method returns fa0 is because 0xfao is not a valid hexadecimal number that its actually a string representation of fa0 in order to make it clear that its a hexadecimal. Actually in either case its a string since the returned value is Returns a string containing a hexadecimal representation of the given unsigned number argument. its just made "print" this can be done by you if you want. –  Ramhound Jan 30 '13 at 14:13
    
It's a lot easier for you to add 0x to the start of a string when you need it than it is to remove it when you don't. –  Hand-E-Food Jan 30 '13 at 21:59
    
I suspect the OP was simply misusing the word "signed". The 0x prefix can be thought of as a sign that the following digits are hexadecimal. The problem is that we almost universally use the word "signed" to refer to a postive-vs-negative indicator. See my answer for more discussion. I'm tempted to edit the question to use clearer terminology, but that would invalidate at least one of the existing answers. The real question being asked is "Why does dechex() not add a 0x prefix?" –  Keith Thompson Jan 31 '13 at 16:22

2 Answers 2

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.

share|improve this answer
    
Additionally, no hexadecimal value is printed with the "0x" prefix in PHP (see eg. sprintf). us.php.net/manual/en/function.sprintf.php –  meisterluk Jan 30 '13 at 12:12
    
Well for instance, in my other question: programmers.stackexchange.com/q/185265/62307, I would want to generate those values myself but I can't because if i create a var with $b = dechex(4000), I don't get a signed variable –  Chud37 Jan 30 '13 at 12:29
    
@Chud37 I don't understand what you are trying to do. Why do think you need to get a signed value? –  phant0m Jan 30 '13 at 12:34
2  
@Chud37 Signed means that a numeric variable can represent both positive and negative numbers. It has absolutely nothing to do with the 0x prefix, the fact that dechex() returns unsigned values is irrelevant to the fact that it doesn't return the (useless) 0x prefix. Where did you read that 0x hexadecimals are called "signed"? That's just wrong, and it's possibly the source of your confusion. –  Yannis Rizos Jan 30 '13 at 12:37
1  
@phant0m Nah, your answer is good, Chud should spend sometime researching base systems (that other answer is also good ;) and signedness. –  Yannis Rizos Jan 30 '13 at 13:04

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%X\n", 1234);
?>

Here's the output:

dechex(12345678)   = "bc614e"
dechex(012345678)  = "53977"
dechex(0xDEADBEEF) = "deadbeef"
dechex(4*5)        = "14"
With a prefix:       "0x14"
0x4d2
0X4D2
share|improve this answer
    
Might want to mention that number that starts with a '0' is interpreted as octal. This is why dechex(123) != dechex(0123) –  MichaelT Jan 30 '13 at 16:15
    
Also, you have to remember that PHP allows to to pass a string to dechex(), within which the number is in fact stored in decimal notation. –  phant0m Jan 30 '13 at 16:28
    
@MichaelT: I mentioned octal in a comment. –  Keith Thompson Jan 30 '13 at 16:45
    
@phant0m: Interesting. I would have expected dechex("0x123") to return "123", but it returns "0" -- and dechex("0123") returns "7b", which is the hexadecimal representation of decimal 123. I suppose it's a matter of how PHP does implicit conversions from strings to numbers? –  Keith Thompson Jan 30 '13 at 16:47
    
Yes, apparently PHP converts it into an integer. If the string starts with a digit, it reads until the first non-digit is read (always assuming decimal notation). Otherwise, it's simply zero. That's why this dechex("1e1"); evaluates to 1 but dechex(0 + "1e1"); evaluates a, because when converting to a number, it also checks whether the strings contains an e or a . for floating-point conversions. I just wanted to give a thought as to why they might have named it dechex instead of inthex or something like that. –  phant0m Jan 30 '13 at 16:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.