(unsigned)-INT_MIN

V

viza

Hi all

int i= INT_MIN;
unsigned int u= -i;

Is u guaranteed to have the absolute value of INT_MIN?

Why it might not: -i has type (int), and -INT_MIN might be more than
INT_MAX.

A cast might not work either, because in (unsigned)-i; the cast is too
late, and in -(unsigned)i then i cannot be represented as unsigned.

If long is longer than int, I can do -(long)i, but what if we are talking
about the longest integer type available?

TIA
viza
 
V

vippstar

Hi all

int i= INT_MIN;
unsigned int u= -i;

Is u guaranteed to have the absolute value of INT_MIN?

Why it might not: -i has type (int), and -INT_MIN might be more than
INT_MAX.
So what? corresponding integer types have the same range of values; If
int has N values, unsigned int has N values.
It is guaranteed.
<snip>
 
R

rahul

Hi all

int i= INT_MIN;
unsigned int u= -i;

Is u guaranteed to have the absolute value of INT_MIN?
On my system, u becomes 0 as INT_MIN is -2147483648 and INT_MAX is
2147483647. So, -INT_MIN wraps around to 0.
Why it might not: -i has type (int), and -INT_MIN might be more than
INT_MAX.
-INT_MIN is greater than INT_MAX on most of the systems.

If long is longer than int, I can do -(long)i, but what if we are talking
about the longest integer type available?
What are we looking at? Is it about getting the absolute value of a
signed int in an unsigned int?
 
V

vippstar

So what? corresponding integer types have the same range of values; If
int has N values, unsigned int has N values.
It is guaranteed.
<snip>


I'm sorry, I misunderstood you. You're interested in the case that
INT_MIN < -INT_MAX.
Well, in that case, computing -INT_MIN invokes undefined behavior;
(overflow)
Try this

if(i == INT_MIN)
u += INT_MAX + (unsigned)-(i + INT_MAX);
u = -i;
 
O

Old Wolf

int i= INT_MIN;
unsigned int u= -i;

Is u guaranteed to have the absolute value of INT_MIN?

No. On a normal (2's complement) system, the
code causes undefined behaviour because the
operation "-i" causes an integer overflow.

Not sure what 'vipps' was on about..
A cast might not work either, because in (unsigned)-i; the cast is too
late, and in -(unsigned)i then i cannot be represented as unsigned.

Signed values can be converted to unsigned ;
(unsigned)i is guaranteed to be UINT_MAX - INT_MIN,
which is INT_MAX on the normal machine.
 
V

vippstar

No. On a normal (2's complement) system, the
code causes undefined behaviour because the
operation "-i" causes an integer overflow.

Not sure what 'vipps' was on about..

Which one of my two (without counting this one) messages are you
refering to?
I posted a follow-up quoting my first message saying I misunderstood,
and then I gave an answer which I believe to be correct. (and
relevant)
Signed values can be converted to unsigned ;
(unsigned)i is guaranteed to be UINT_MAX - INT_MIN,
which is INT_MAX on the normal machine.

Wrong.
Assuming i is -N with N >= 0, (unsigned)i is UINT_MAX - N + 1.
So (unsigned)INT_MIN would be UINT_MAX + INT_MIN + 1.
 
V

vippstar

On Jul 21, 12:36 pm, (e-mail address removed) wrote:
Try this

if(i == INT_MIN)
u += INT_MAX + (unsigned)-(i + INT_MAX);
u = -i;
^
insert 'else' there... :-( I should be looking twice at my messages
before posting them.
 
V

viza

Hi

int i= INT_MIN;
unsigned int u= -i;

Is u guaranteed to have the absolute value of INT_MIN?
If long is longer than int, I can do -(long)i, but what if we are
talking about the longest integer type available?

Thanks for the answers so far, but none of them help. Perhaps I can
explain it a bit better:

What I would like is a constant expression of unsigned type for the
absolute value of an constant negative expression of the corresponding
signed type.

Ie:

1) I know i is negative
2) I want (unsigned)abs(i)

The answer simply: ( (unsigned)-i ) for any i except INT_MIN. What is
the answer for INT_MIN? or for any i?

Thanks,

viza
 
V

viza

Hi

What I would like is a constant expression of unsigned type for the
absolute value of an constant negative expression of the corresponding
signed type.
Thanks for the answers so far, but none of them help

I could use a conditional operation based on vippstars second post, but
is there a neater way?

viza
 
O

Old Wolf

Which one of my two (without counting this one) messages are you
refering to?

I was referring to your first post on this thread
(and I posted before you posted your correction).
Wrong.
Assuming i is -N with N >= 0, (unsigned)i is UINT_MAX - N + 1.
So (unsigned)INT_MIN would be UINT_MAX + INT_MIN + 1.

Knew I should have checked that more before
posting .. the baby was crying though :)
 
O

Old Wolf

What I would like is a constant expression of unsigned type for the
absolute value of an constant negative expression of the corresponding
signed type.

-(unsigned)i

Assuming i is negative, then:
(unsigned)i is UINT_MAX + 1 - abs(i)
so the negative of that is
UINT_MAX + 1 - (UINT_MAX + 1 - abs(i))
which is abs(i).
 
V

vippstar

There is no integer type which is guaranteed
to be able to represent the absolute value of INT_MIN.

That's incorrect. Do you mean no signed integer type? If so, that is
correct.
unsigned int, unsigned long int, unsigned long long int, all can
represent the absolute value of INT_MIN.
 
K

Keith Thompson

That's incorrect. Do you mean no signed integer type? If so, that is
correct.
unsigned int, unsigned long int, unsigned long long int, all can
represent the absolute value of INT_MIN.

That's true on most systems, but it's not guaranteed by the standard.

A conforming system could have padding bits in unsigned int, so that
UINT_MAX == INT_MAX. And unsigned long int and unsigned long long int
could both have the same size and representation as unsigned int
(assuming UINT_MAX >= 2**64-1).

Such a system is unlikely to exist in real life. int and unsigned int
would have to be at least 65 bits (33 bits if you'll settle for C90
conformance).
 
L

lawrence.jones

viza said:
int i= INT_MIN;
unsigned int u= -i;

Is u guaranteed to have the absolute value of INT_MIN?

No, for the reason you give:
Why it might not: -i has type (int), and -INT_MIN might be more than
INT_MAX.
A cast might not work either, because in (unsigned)-i; the cast is too
late,
Correct.

and in -(unsigned)i then i cannot be represented as unsigned.

No, i can always be represented as unsigned because conversion to
unsigned is done modulo (UINT_MAX + 1). Since unsigned negation is
equivalent to subtracting the value from (UINT_MAX + 1), -(unsigned)i
produces the value (UINT_MAX + 1) - (UINT_MAX + 1 + i), which is -i and
exactly what you want, provided -INT_MAX is actually representable as an
unsigned. Although that is almost certainly true in practice, it is not
guaranteed by the standard.
 
V

viza

Hi all
int i= INT_MIN;
unsigned int u= -i;

Is u guaranteed to have the absolute value of INT_MIN?

I've solved it:

int i= INT_MIN;
unsigned int u= 0U-(unsigned)i;

For any negative valued expression i of signed integer type t

( 0U - (unsigned t) i )

is an expression with compatible unsigned type having the absolute value
of i. No signed intermediates are used so it works even with INT_MIN on
a twos compliment implementation.

This has taken too long for something so trivial. IMHO it's stupid that
abs() has signed return type. All I really needed was a function like:

unsigned int uabs( int i ){
return (0<i) ? ((unsigned int)i) : (0U-(unsigned int)i);
}
 
V

viza

For any negative valued expression i of signed integer type t

( 0U - (unsigned t) i )

is an expression with compatible unsigned type having the absolute value
of i.

....if one exists.
 
P

Peter Nilsson

viza said:
I've solved it:

No you haven't.
int i= INT_MIN;
unsigned int u= 0U-(unsigned)i;

The cast is redundant in context.

unsigned u = 0u - i; /* or... */
unsigned u = - (unsigned) INT_MIN;
For any negative valued expression i of signed integer type t

( 0U - (unsigned t) i )

Except INT_MIN on an implementation where UINT_MAX == INT_MAX.
is an expression with compatible unsigned type having the absolute value
of i. No signed intermediates are used so it works even with INT_MIN on
a twos compliment implementation.

With 1 exception.
This has taken too long for something so trivial. IMHO it's stupid that
abs() has signed return type.

Well it's easy to criticise with 40 years of hindsight.
All I really needed was a function like:

unsigned int uabs( int i ){
return (0<i) ? ((unsigned int)i) : (0U-(unsigned int)i);
}

Or you may be able to modify your algorithm to not care about the
absolute value. That would be the better course. In fact, it often
leads to efficiencies.
 
V

vippstar

That's true on most systems, but it's not guaranteed by the standard.

A conforming system could have padding bits in unsigned int, so that
UINT_MAX == INT_MAX. And unsigned long int and unsigned long long int
could both have the same size and representation as unsigned int
(assuming UINT_MAX >= 2**64-1).

Such a system is unlikely to exist in real life. int and unsigned int
would have to be at least 65 bits (33 bits if you'll settle for C90
conformance).

I thought that corresponding integer types have both N range values?
 
K

Keith Thompson

I thought that corresponding integer types have both N range values?

No, that's not required (if I understand you correctly). Both signed
int and unsigned int are allowed to have padding bits; there's no
requirement that they have the same number of padding bits.

An implementation where:

int and unsigned int are both 32 bits;

int has 31 value bits and 1 sign bit, with a range of
-2147483648 .. 2147483647;

unsigned int has 31 value bits and 1 padding bit, with a range
of 0 .. 2147483647

could be conforming. It would even be sensible on an implementation
where the hardware doesn't support unsigned arithmetic, or where
signed and unsigned integers are represented as floating-point with a
fixed exponent.
 
V

vippstar

(e-mail address removed) writes:

No, that's not required (if I understand you correctly). Both signed
int and unsigned int are allowed to have padding bits; there's no
requirement that they have the same number of padding bits.

An implementation where:
<snip>

Again, I misunderstood a reply from a previous thread.
Thanks.
 

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

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top