Print a signel octal

L

laurent.pauloin

Hello,

I would like to print a signed octal.
With a signed short it's printf %hi but what about an octal ?

Tk !
 
P

Philip Potter

Ali said:

That's the format specifier for an unsigned short to be formatted as an
octal, not for a signed int formatted as an octal.

The *printf() functions don't provide what the OP wants. If you want a
signed int printed as an octal you can do this:

printf("%c%o",octal<0 ? '-' : ' ', octal<0 ? -octal : octal);

...although this may fail for octal < -INT_MAX.

Phil
 
M

Martin Ambuhl

Hello,

I would like to print a signed octal.
With a signed short it's printf %hi but what about an octal ?

The octal ("%o") and hex ("%x" or "%X") specifiers are for unsigned
values. If you truly want to print values as signed, consider code like
the following. You might also want to think about what things might be
done better. Note that if you start with a signed int value, you should
probably memmove or memcpy it to an unsigned int used as the argument
for show_signed_octal (unless you _know_ your clever pointer trick is
legal and works).

#include <stdio.h>
#include <limits.h>

void show_signed_octal(unsigned int a)
{
if (a <= INT_MAX)
printf("argument a = %#o is non-negative.\n\n", a);
else {
printf("argument a = %#o is negative,\n ", a);
a = 1 + ~a;
printf(" 1 + ~a = -%#o, \n", a);
a = 1 + ~a;
printf(" 1 + ~(1 + ~a) = %#o.\n\n", a);
}
}

int main(void)
{
unsigned int x = 0, increment = UINT_MAX / 13, i;
show_signed_octal(0);
for (i = 1; i < 14; i++) {
x += increment;
show_signed_octal(x);
}
show_signed_octal((unsigned) INT_MIN);
show_signed_octal((unsigned) INT_MAX);
show_signed_octal(UINT_MAX);
return 0;
}


[Output for one implementation]
argument a = 0 is non-negative.

argument a = 02354235423 is non-negative.

argument a = 04730473046 is non-negative.

argument a = 07304730471 is non-negative.

argument a = 011661166114 is non-negative.

argument a = 014235423537 is non-negative.

argument a = 016611661162 is non-negative.

argument a = 021166116605 is negative,
1 + ~a = -016611661173,
1 + ~(1 + ~a) = 021166116605.

argument a = 023542354230 is negative,
1 + ~a = -014235423550,
1 + ~(1 + ~a) = 023542354230.

argument a = 026116611653 is negative,
1 + ~a = -011661166125,
1 + ~(1 + ~a) = 026116611653.

argument a = 030473047276 is negative,
1 + ~a = -07304730502,
1 + ~(1 + ~a) = 030473047276.

argument a = 033047304721 is negative,
1 + ~a = -04730473057,
1 + ~(1 + ~a) = 033047304721.

argument a = 035423542344 is negative,
1 + ~a = -02354235434,
1 + ~(1 + ~a) = 035423542344.

argument a = 037777777767 is negative,
1 + ~a = -011,
1 + ~(1 + ~a) = 037777777767.

argument a = 020000000000 is negative,
1 + ~a = -020000000000,
1 + ~(1 + ~a) = 020000000000.

argument a = 017777777777 is non-negative.

argument a = 037777777777 is negative,
1 + ~a = -01,
1 + ~(1 + ~a) = 037777777777.
 
M

Martin Ambuhl

Ali said:

"%o" (and "%ho") are *defined* as taking unsigned values to be shown as
unsigned. Your "solution" in no way addresses the question of printing
"signed octal".
 
P

Philip Potter

Philip said:
That's the format specifier for an unsigned short to be formatted as an
octal, not for a signed int formatted as an octal.

The *printf() functions don't provide what the OP wants. If you want a
signed int printed as an octal you can do this:

printf("%c%o",octal<0 ? '-' : ' ', octal<0 ? -octal : octal);

Argh! This should be:

short octal = f(); /* f() gets the value to be printed */
unsigned short value = (octal<0) ? -octal : octal;
printf("%c%o",octal<0 ? '-' : ' ', value);

...because before I was passing a signed value where printf() expected
unsigned.
 
T

Tor Rustad

Martin Ambuhl wrote:

[...]
The octal ("%o") and hex ("%x" or "%X") specifiers are for unsigned
values. If you truly want to print values as signed, consider code like
the following. You might also want to think about what things might be
done better.


I would like to suggest an improvement too. :)

#include <stdio.h>
#include <limits.h>

void show_signed_octal(unsigned int a)
{
if (a <= INT_MAX)
printf("argument a = %#o is non-negative.\n\n", a);
else {
printf("argument a = %#o is negative,\n ", a);
a = 1 + ~a;
printf(" 1 + ~a = -%#o, \n", a);
a = 1 + ~a;
printf(" 1 + ~(1 + ~a) = %#o.\n\n", a);
}
}

For signed integer types, it's implementation-defined, if the object
representation with sign bit 1 and the value bits equal, is a trap
representation or not.

Not assuming 2's complement machine:


void print_octal(int signed_num)
{
if (signed_num < 0)
{
printf("-%#o\n", (unsigned int)(signed_num * (-1)) );
}
else
{
printf("%#o\n", (unsigned int)signed_num);
}
}
 
P

Philip Potter

Tor said:
Martin Ambuhl wrote:

[...]
The octal ("%o") and hex ("%x" or "%X") specifiers are for unsigned
values. If you truly want to print values as signed, consider code like
the following. You might also want to think about what things might be
done better.
#include <stdio.h>
#include <limits.h>

void show_signed_octal(unsigned int a)
{
if (a <= INT_MAX)
printf("argument a = %#o is non-negative.\n\n", a);
else {
printf("argument a = %#o is negative,\n ", a);
a = 1 + ~a;
printf(" 1 + ~a = -%#o, \n", a);
a = 1 + ~a;
printf(" 1 + ~(1 + ~a) = %#o.\n\n", a);
}
}

For signed integer types, it's implementation-defined, if the object
representation with sign bit 1 and the value bits equal, is a trap
representation or not.

It's lucky that Martin didn't deal with signed integer types then.
Not assuming 2's complement machine:

Martin's didn't either, though I initially thought it did. Because it
takes an unsigned int argument, any negative numbers will first be
shifted into the range of unsigned int, when the 1 + ~a operation
correctly gets the absolute value of the original negative number:

For example:
show_signed_octal(-3);

With any signed integer representation, -3 when converted to unsigned
int becomes UINT_MAX+1-3, which will be represented as
....111101 (any number of leading ones)
after complement and add one the representation is
....000011 (any number of leading zeroes)
which has value 3. Hey presto!

Phil
 
J

Joe Wright

Philip said:
Tor said:
Martin Ambuhl wrote:

[...]
The octal ("%o") and hex ("%x" or "%X") specifiers are for unsigned
values. If you truly want to print values as signed, consider code
like the following. You might also want to think about what things
might be done better.
#include <stdio.h>
#include <limits.h>

void show_signed_octal(unsigned int a)
{
if (a <= INT_MAX)
printf("argument a = %#o is non-negative.\n\n", a);
else {
printf("argument a = %#o is negative,\n ", a);
a = 1 + ~a;
printf(" 1 + ~a = -%#o, \n", a);
a = 1 + ~a;
printf(" 1 + ~(1 + ~a) = %#o.\n\n", a);
}
}

For signed integer types, it's implementation-defined, if the object
representation with sign bit 1 and the value bits equal, is a trap
representation or not.

It's lucky that Martin didn't deal with signed integer types then.
Not assuming 2's complement machine:

Martin's didn't either, though I initially thought it did. Because it
takes an unsigned int argument, any negative numbers will first be
shifted into the range of unsigned int, when the 1 + ~a operation
correctly gets the absolute value of the original negative number:

For example:
show_signed_octal(-3);

With any signed integer representation, -3 when converted to unsigned
int becomes UINT_MAX+1-3, which will be represented as
...111101 (any number of leading ones)
after complement and add one the representation is
...000011 (any number of leading zeroes)
which has value 3. Hey presto!

Phil
/*
Signed Octal?
*/

#include <stdio.h>

int main(void) {
int a = 123;
int b = -123;
printf("%s%o\n", a < 0 ? "-" : "", a < 0 ? -a : a);
printf("%s%o\n", b < 0 ? "-" : "", b < 0 ? -b : b);
return 0;
}
 
P

Philip Potter

Joe said:
/*
Signed Octal?
*/

#include <stdio.h>

int main(void) {
int a = 123;
int b = -123;
printf("%s%o\n", a < 0 ? "-" : "", a < 0 ? -a : a);
printf("%s%o\n", b < 0 ? "-" : "", b < 0 ? -b : b);
return 0;
}
This code is almost identical to code I've already posted elsethread in
message <[email protected]>. It even has the same bug!

Phil
 

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
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top