Question about octal

M

Mateusz_madi

Hi, can anybody explain why thist prog
#include<stdio.h>

int main()
{
int sx = -1;
unsigned ux = -1;
printf("%o\n", sx);
printf("%o\n", ux);
}
will print:

37777777777
37777777777

I mean how are values below zero evaluates in octal format?

regards
Mateusz
 
M

Malcolm McLean

Hi, can anybody explain why thist prog
#include<stdio.h>

int main()
{
 int sx = -1;
 unsigned ux = -1;
 printf("%o\n", sx);
 printf("%o\n", ux);}

will print:

37777777777
37777777777

I mean how are values below zero evaluates in octal format?
In a twos complement system, -1 is all bits set. (To substract you
invert, increment and add, discarding the overflow).

In octal 777777 repested is all bits set. The 3 is because the 3 bits
of octal don't make up a whole 32 bits.

unsigned ux = -1; should generate an error, and would in most
languages. In C it's allowed because it's an old language and people
were playing fast and loose with types and representations. It sets ux
to the same bit pattern as -1 in signed integers.
 
L

lawrence.jones

Malcolm McLean said:
unsigned ux = -1; should generate an error, and would in most
languages. In C it's allowed because it's an old language and people
were playing fast and loose with types and representations. It sets ux
to the same bit pattern as -1 in signed integers.

No, it doesn't. It sets it to the maximum possible value, which won't
be the same bit pattern as -1 in signed integers unless the system uses
2's complement notation. In C, unsigned numbers aren't just unsigned,
they're also modulo -- they're guaranteed to wrap around from the
largest possible value to zero and vice versa.
 
O

osmium

Mateusz_madi said:
Hi, can anybody explain why thist prog
#include<stdio.h>

int main()
{
int sx = -1;
unsigned ux = -1;
printf("%o\n", sx);
printf("%o\n", ux);
}
will print:

37777777777
37777777777

I mean how are values below zero evaluates in octal format?

Think of octal as just an encoding, a shorthand way to represent binary
numbers. Don't think of it as a (the?) base 8 sytsem of numbers.
 
R

Ralf Damaschke

China Blue Ribbon said:
The only place I see octal anymore are unix st_modes.

Don't tell me that current C programs don't use the constant 0 ;-)
cf. 6.4.4.1

-- Ralf
 
K

Keith Thompson

Mateusz_madi said:
Hi, can anybody explain why thist prog
#include<stdio.h>

int main()
{
int sx = -1;
unsigned ux = -1;
printf("%o\n", sx);
printf("%o\n", ux);
}
will print:

37777777777
37777777777

I mean how are values below zero evaluates in octal format?

Strictly speaking, your program's behavior is undefined. (That
doesn't mean it's going to blow up, just that the C standard doesn't
say what it will do.) The "%o" format requires an unsigned int
argument; in your first printf call, your passing it a (signed) int.
This is ok *if* the signed int value is within the numeric range
representable as an unsigned int, but in this case it isn't.

In practice, what will almost certainly happen is that the
*representation* of the signed int value will be interpreted as if it
were an unsigned int. On a two's-complement system, (int)-1 has the
same bit pattern as (unsigned int)UINT_MAX, which apparently is 2**32-1
on your system (4294967295 decimal, 037777777777 octal).

Note that the declaration
unsigned ux = -1;
doesn't store a negative value in ux (it can't). Instead, the int
value -1 is converted from int to unsigned int; by the language's
conversion rules, the result is guaranteed to be UINT_MAX.
 
S

Seebs

Hi, can anybody explain why thist prog

Hi. I'd like to suggest that you proofread a little more carefully;
showing an interest in how you present your posts increases the willingness
of other people to answer your questions.
int main()
{
int sx = -1;
unsigned ux = -1;
printf("%o\n", sx);
printf("%o\n", ux);
}

You may want to consider the implications of the fact that you used the
same format string both times. How would printf() know that it had two
different kinds of arguments? It wouldn't. %o tells it how to interpret
its input.
I mean how are values below zero evaluates in octal format?

This is the wrong question. Octal isn't at issue; signed/unsigned is. You
appear to be on a machine using "twos complement" arithmetic (the most common
kind for most people today), on which the value -1 in a signed object, and
the value -1 gets converted to when converted to unsigned, have the same
representation, which is all-bits-1.

The octal specifier has nothing to do with values below zero, it's just
representing the bits you gave it. It doesn't care whether you think they're
below zero or not.

-s
 
A

Alan Curry

Hi, can anybody explain why thist prog
#include<stdio.h>

int main()
{
int sx = -1;
unsigned ux = -1;
printf("%o\n", sx);
printf("%o\n", ux);
}

Answered well enough already, but I'd like to add this:

There would have been less chance for confusion here if printf had
included separate specifiers for printing negative values in hex and
octal, just like it has %d and %u for decimal. If you want to print the
value -255 as "-FF", printf doesn't make it easy.

Base and signedness are orthogonal, printf doesn't treat them that way.

%u should have been %ud (u as a modifier, not a primary). %uo, %ux,
and %uX would have followed naturally.
 
M

Mateusz_madi

I don't know if I understood weel, so if i say:
int sx = -1;
unsigned ux = -1;

and hav a machine using twos complement arithmetic, values goes:
printf("%o\n", sx) -> 11111111...1111 -> 3FFF...FF
and
printf("%o\n", sx)->printf("%o\n", ux) -> 11111111...1111 ->
3FFF...FF

Ism't it?
 
H

Hans Vlems

I don't know if I understood weel, so if i say:
int sx = -1;
unsigned ux = -1;

and hav a machine using twos complement arithmetic, values goes:
 printf("%o\n", sx) -> 11111111...1111 ->  3FFF...FF
and
printf("%o\n", sx)->printf("%o\n", ux) -> 11111111...1111 ->
3FFF...FF

Ism't it?

Perhaps. Try to predict the output of this:

#include<stdio.h>

int main(void)
{
int sx;
for (sx=-10;sx<12;sx+=1)
printf("%d %u %o %x\n",sx,(unsigned) sx,sx,sx);
return 0;
}

Again, try to predict the output and don't look at the C coding style.

Hans
 
M

Mateusz_madi

I think i got it, but to be shure, let's say i've got:
int x = -10;
printf("%d %u %o %x\n", x , (unsigned) x, x , x);

-1 is binary 111111....1111

It will evaluate:
1) %d - x -> just -10
2) %u -> (unsigned)x -> %u -> 111111...1111(unsigned, there is no inf
to tread this 1111...1111 as -1 because it beacme unsigned, so) -> %u
- (2^32-10)
3) %o - x -> %o - 1111...1111 (hidden become unsigned) -> %o -
111111...111 -> %o - 111111...1111 0110 (octally number is 3 bit so) -
%o - 377...766
4) %x - x -> %x - 1111...1111 (hidden become unsigned) -> %x -
11111...1111 -> %x - 111111...1111 0110 (hex takes 4 bits so) -> %x -
FFF...F6

Isn't it?

regards, mateusz
 
K

Keith Thompson

Mateusz_madi said:
I don't know if I understood weel, so if i say:
int sx = -1;

This initializes sx to -1.
unsigned ux = -1;

This initializes ux to UINT_MAX, the result of converting -1 from
int to unsigned int.
and hav a machine using twos complement arithmetic, values goes:
printf("%o\n", sx) -> 11111111...1111 -> 3FFF...FF
and
printf("%o\n", sx)->printf("%o\n", ux) -> 11111111...1111 ->
3FFF...FF

Ism't it?

Maybe.

sx is a signed int; "%o" requires an unsigned int. You can pass a
signed int where an unsigned int is expected, or vice versa, *only*
if the value is within the range of representable by both types
(0 .. INT_MAX); otherwise, the behavior is undefined.

In principle, your program (or rather, a complete program that
includes your code fragments) can do literally anything.

In practice, printf will almost certainly interpret the
representation of sx (a signed int) as if it were an object of type
unsigned int, and on a 2's-complement system it will probably behave
as you expect (except that the output will be octal, not hexadecimal
as you've shown).

For example, on my system, this program:

#include <stdio.h>

int main(void)
{
int sx = -1;
unsigned int ux = -1;

printf("ux = %o (undefined behavior) \n", ux);
printf("sx = %o\n", sx);
return 0;
}

produces this output:

ux = 37777777777 (undefined behavior)
sx = 37777777777
 
F

Francois Grieu

I think i got it, but to be shure, let's say i've got:
int x = -10;
printf("%d %u %o %x\n", x , (unsigned) x, x , x);

%u %o and %x all expect unsigned int arguments. Thus either
your (unsigned) x could be x, or you missed two (unsigned).
I suspect the later, and that it could make a difference on
systems not using 2's complement (I won't bet a hand at that).
-1 is binary 111111....1111

for some creative definition of "is", including use of 2's complement.
It will evaluate:
1) %d - x -> just -10
Yes.

2) %u -> (unsigned)x -> %u -> 111111...1111(unsigned, there is no inf
to tread this 1111...1111 as -1 because it became unsigned, so) -> %u
-> (2^32-10)

I suspect that the decimal representation for UINT_MAX-9 will be output;
this may or may not be 4294967286.
3) %o - x -> %o - 1111...1111 (hidden become unsigned) -> %o
-> 111111...111 -> %o - 111111...1111 0110 (octal number is 3 bit so)
-> %o - 377...766

4) %x - x -> %x - 1111...1111 (hidden become unsigned) -> %x ->
11111...1111 -> %x - 111111...1111 0110 (hex takes 4 bits so) -> %x
-> FFF...F6

Isn't it?

I suspect the output for these is even harder to predict. Looks like
it depends in the number of bits in int; and the internal representation
of negative numbers, which is fully undefined under C89 (C99 allows three
options).

Francois Grieu
 
H

Hans Vlems

I think i got it, but to be shure, let's say i've got:
int x = -10;
printf("%d %u %o %x\n", x , (unsigned) x, x , x);

-1 is binary 111111....1111

It will evaluate:
1) %d - x -> just -10
2) %u -> (unsigned)x -> %u -> 111111...1111(unsigned, there is no inf
to tread this 1111...1111 as -1 because it beacme unsigned, so) -> %u
- (2^32-10)
3) %o - x -> %o - 1111...1111 (hidden become unsigned) -> %o -
111111...111 ->  %o - 111111...1111 0110 (octally number is 3 bit so) -> %o - 377...766

4) %x - x -> %x - 1111...1111 (hidden become unsigned) -> %x -
11111...1111 ->  %x - 111111...1111 0110 (hex takes 4 bits so) -> %x -
FFF...F6

Isn't it?

regards, mateusz

Correct. The little exercise shows the difference between the contents
of a 32 bit binary value and a few possible representations. May be
incorrectly, I got the feeling that you were somewhat lost in that
respect.
Hans
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top