Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

taking abs() of min signed int value

98 views
Skip to first unread message

Jeremy Todd

unread,
May 16, 2012, 1:39:06 PM5/16/12
to
Hi,

I need to compute the absolute value of the minimum signed int value
for each signed integral type. This value isn't representable as a
signed int, but it is representable as an unsigned int.

This is easy when a larger signed type is available:

int32_t min_int32 = std::numeric_limits<int32_t>::min();
int64_t abs_min_int32= -int64_t(min_int32);
uint32_t answer = uint32_t(abs_min_int32);

I couldn't come up with an elegant solution when attempting this for
the 64-bit type. With a two's complement representation, it just so
happens that reinterpreting the min signed int as an unsigned value
produces the correct result:

int64_t min_int64 = std::numeric_limits<int64_t>::min();
uint64_t answer = uint64_t(min_int64);

but this felt rather inelegant. Can anyone think of a more elegant
solution that does not assume a two's complement binary
representation?

I should note that the standard does not seem to require that
abs(min_int) is representable as a uint for a given size, so let's
limit our consideration to platforms where it is representable.

Regards,
Jeremy


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Marc

unread,
May 16, 2012, 8:24:53 PM5/16/12
to
Jeremy Todd wrote:

> I need to compute the absolute value of the minimum signed int value
> for each signed integral type. This value isn't representable as a
> signed int, but it is representable as an unsigned int.
>
> This is easy when a larger signed type is available:
>
> int32_t min_int32 = std::numeric_limits<int32_t>::min();
> int64_t abs_min_int32= -int64_t(min_int32);
> uint32_t answer = uint32_t(abs_min_int32);
>
> I couldn't come up with an elegant solution when attempting this for
> the 64-bit type. With a two's complement representation, it just so
> happens that reinterpreting the min signed int as an unsigned value
> produces the correct result:
>
> int64_t min_int64 = std::numeric_limits<int64_t>::min();
> uint64_t answer = uint64_t(min_int64);
>
> but this felt rather inelegant. Can anyone think of a more elegant
> solution that does not assume a two's complement binary
> representation?

Casting a signed type to an unsigned one has a well-defined modular
meaning. When you cast min_int64 to uint64_t, you get something that
is the same as min_int64 modulo 2^64 (hence 2^64+min_int64). You can
then apply operator- to this and get something equal to -min_int64
modulo 2^64. And that's the number you are looking for. In short:
uint64_t answer = - (uint64_t)(min_int64);

Ulrich Eckhardt

unread,
May 16, 2012, 8:28:22 PM5/16/12
to
Jeremy Todd wrote:
> I need to compute the absolute value of the minimum signed int value
> for each signed integral type. This value isn't representable as a
> signed int, but it is representable as an unsigned int.
>
> This is easy when a larger signed type is available:
>
> int32_t min_int32 = std::numeric_limits<int32_t>::min();
> int64_t abs_min_int32= -int64_t(min_int32);
> uint32_t answer = uint32_t(abs_min_int32);
>
> I couldn't come up with an elegant solution when attempting this for
> the 64-bit type.


You could use the fact that "min == min/2 + (min - min/2)" and that the
absolute of the two summands can be represented as the according *int_t.

Uli

Kaba

unread,
May 17, 2012, 9:45:44 AM5/17/12
to
Jeremy Todd wrote:
> I need to compute the absolute value of the minimum signed int value
> for each signed integral type. This value isn't representable as a
> signed int, but it is representable as an unsigned int.

A way out of these problems is to never use the smallest value of a
signed integer. For example, if you store a sound signal in a 16bit
signed integer, use the range [-(2^16 - 1), 2^16 - 1]. The non-existence
of the additive inverse of -2^n makes the value unusable. From this
restriction follows other advantages such as being able to form a
bijection between the integer values and floating point numbers (useful
for lossless sound conversion between integers and floating point
numbers). Similarly for any data which is quantized from real numbers.

--
http://kaba.hilvi.org
0 new messages