What Does It Mean When a Numeric Constant in C/C++ Is Prefixed With a 0

What does it mean when a numeric constant in C/C++ is prefixed with a 0?

In C/C++ a numeric literal prefixed with a '0' is octal (base 8).

See http://www.cplusplus.com/doc/tutorial/constants/

overloading inserters and strange output(for '20' and '020')

0 is the octal prefix for C++ integer literals and 20 in octal is 16 in decimal.

To explain further: If a literal starts with 0 the rest of the number will be interpreted to be in octal representation. In your example 2*8^1 + 0 * 8^0.

The syntax for integer literals is given in §2.14.2 in the most recent standard draft.

What's happening to an int that starts with 0? ex 00101

Then the integer is treated as an octal number. So,

01001

equals

1 * 8 ^ 0 + 0 * 8 ^ 1 + 0 * 8 ^ 2 + 1 * 8 ^ 3 = 1 + 0 + 0 + 512 = 513

No magic in there.

Bitwise OR Operator

The OR operator is a red-herring: the issue is elsewhere.

010 is an octal literal due to the leading 0. In decimal, this is 8.

So x has the value 8 in decimal. And 8 | 4 is 12.

10 is a decimal literal. And 10 | 4 is 14.

C++ int with preceding 0 changes entire value

An integer literal that starts from 0 defines an octal integer literal. Now in C++ there are four categories of integer literals

integer-literal:
decimal-literal integer-suffixopt
octal-literal integer-suffixopt
hexadecimal-literal integer-suffixopt
binary-literal integer-suffixopt

And octal-integer literal is defined the following way

octal-literal:
0 octal-literal
opt octal-digit

That is it starts from 0.

Thus this octal integer literal

0110

corresponds to the following decimal number

8^2 + 8^1 

that is equal to 72.

You can be sure that 72 in octal representation is equivalent to 110 by running the following simple program

#include <iostream>
#include <iomanip>

int main()
{
std::cout << std::oct << 72 << std::endl;

return 0;
}

The output is

110

How does C Handle Integer Literals with Leading Zeros, and What About atoi?

Leading zeros indicate that the number is expressed in octal, or base 8; thus, 010 = 8. Adding additional leading zeros has no effect; just as you would expect in math, x + 0*8^n = x; there's no change to the value by making its representation longer.

One place you often see this is in UNIX file modes; 0755 actually means 7*8^2+5*8+5 = 493; or with umasks such as 0022 = 2*8+2 = 10.

atoi(nptr) is defined as equivalent to strtol(nptr, (char **) NULL, 10), except that it does not detect errors - as such, atoi() always uses decimal (and thus ignores leading zeros). strtol(nptr, anything, 0) does the following:

The string may begin with an arbitrary
amount of white space (as determined
by isspace(3)) followed by a single
optional '+' or '-' sign. If base is
zero or 16, the string may then
include a "0x" prefix, and the number
will be read in base 16; otherwise, a
zero base is taken as 10 (decimal)
unless the next character is '0', in
which case it is taken as 8 (octal).

So it uses the same rules as the C compiler.

Printing the value of integer data type using %x in printf statement

In C, a constant prefixed with a 0 is an octal constant. 0100 in base 8 is
1000000 in base 2, which is 40 in hexadecimal, which is 64 in base 10. So your program is printing exactly what it should.

Why are integers converted to octal numbers here?

Any integer literal that starts with a 0 followed by other digits is octal, just like any integer literal starting with 0x or 0X, followed by digits, is hexadecimal. C++14 will add 0b or 0B as a prefix for binary integer literals.

See more on integer literals in C++ here.



Related Topics



Leave a reply



Submit