By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,123 Members | 1,256 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,123 IT Pros & Developers. It's quick & easy.

std::abs problem

P: n/a
If I include <cmathand write std::abs in my program I get:

gcc -MD -o /home/bla/c++/.build/generator.o -c
generator.cpp
generator.cpp: In function 'int main(int, char**)':
generator.cpp:206: error: call of overloaded 'abs(unsigned int)' is
ambiguous
/usr/include/gentoo-multilib/amd64/stdlib.h:786: note: candidates are:
int abs(int)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/include/g++-v4/cstdlib:143: note:
long int std::abs(long int)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/include/g++-v4/cstdlib:173: note:
long long int __gnu_cxx::abs(long long int)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/include/g++-v4/cmath:90: note:
double std::abs(double)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/include/g++-v4/cmath:94: note:
float std::abs(float)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/include/g++-v4/cmath:98: note:
long double std::abs(long double)
make: *** [/home/bla/c++/.build/generator.o] Error 1

The problem is there is no templated std::abs(), like there is
std::max(). Do I do:

template <class T>
T abs(T const& in)
{
return std::max(-in, in);
}

or something like that? Maybe there's a more beautiful solution? Perhaps
there's something in boost?
Mar 19 '07 #1
Share this Question
Share on Google+
13 Replies


P: n/a
John Doe wrote:
If I include <cmathand write std::abs in my program I get:

gcc -MD -o /home/bla/c++/.build/generator.o -c
generator.cpp
generator.cpp: In function 'int main(int, char**)':
generator.cpp:206: error: call of overloaded 'abs(unsigned int)' is
ambiguous
/usr/include/gentoo-multilib/amd64/stdlib.h:786: note: candidates are:
int abs(int)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/include/g++-v4/cstdlib:143:
note: long int std::abs(long int)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/include/g++-v4/cstdlib:173:
note: long long int __gnu_cxx::abs(long long int)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/include/g++-v4/cmath:90: note:
double std::abs(double)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/include/g++-v4/cmath:94: note:
float std::abs(float)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/include/g++-v4/cmath:98: note:
long double std::abs(long double)
make: *** [/home/bla/c++/.build/generator.o] Error 1

The problem is there is no templated std::abs(), like there is
std::max(). Do I do:

template <class T>
T abs(T const& in)
{
return std::max(-in, in);
}

or something like that? Maybe there's a more beautiful solution?
Perhaps there's something in boost?
I think you're missing the simple fact that you're trying to get
an absolute value of an *unsigned* expression. There is no need to
do that. There are no negative unsigned ints. If you *have to*
specialise 'std::abs' for 'unsigned', you're free to do so:

namespace std { template<abs(unsigned int u) { return u; } }

But then again, perhaps you need to read the error message a bit more
carefully and consider *why* you're trying to find an absolute value
of an unsigned int expression...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 19 '07 #2

P: n/a
But then again, perhaps you need to read the error message a bit more
carefully and consider *why* you're trying to find an absolute value
of an unsigned int expression...
It's you who is in error, as the difference of 2 unsigned numbers may
well be negative. Here's the line from my program:

std::abs(n - m);

where we are subtracting unsigned ints. The result may well turn
negative and what then?
Mar 19 '07 #3

P: n/a
Ah no, you were right and me wrong/ignorant

If during the evaluation of an expression, the result is not
mathematically defined or not in the range of rep-
resentable values for its type, the behavior is undefined, unless such
an expression is a constant expression
(5.19), in which case the program is ill-formed. [Note: most existing
implementations of C++ ignore integer
overflows. Treatment of division by zero, forming a remainder using a
zero divisor, and all floating point
exceptions vary among machines, and is usually adjustable by a library
function. ]

So what I was doing was undefined.
Mar 19 '07 #4

P: n/a
John Doe wrote:
>But then again, perhaps you need to read the error message a bit more
carefully and consider *why* you're trying to find an absolute value
of an unsigned int expression...

It's you who is in error, as the difference of 2 unsigned numbers may
well be negative.
Not in C++.
Here's the line from my program:

std::abs(n - m);

where we are subtracting unsigned ints. The result may well turn
negative and what then?
I think you're mistaken. The result of any arithmetic operation between
two values of type 'unsigned' is of type 'unsigned'.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 19 '07 #5

P: n/a
John Doe wrote:
Ah no [..]

So what I was doing was undefined.
No, the type 'unsigned' behaves as if every operation is modulo 2^bits
where 'bits' is the number of bits in the representation.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 19 '07 #6

P: n/a
On 19 Mar, 17:39, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
John Doe wrote:
But then again, perhaps you need to read the error message a bit more
carefully and consider *why* you're trying to find an absolute value
of an unsigned int expression...
It's you who is in error, as the difference of 2 unsigned numbers may
well be negative.

Not in C++.
Here's the line from my program:
std::abs(n - m);
where we are subtracting unsigned ints. The result may well turn
negative and what then?

I think you're mistaken. The result of any arithmetic operation between
two values of type 'unsigned' is of type 'unsigned'.
Aha.. Another bullet point for my "Don't use unsigned unless you
really have to" armory !

:-)

regards
Andy Little


Mar 19 '07 #7

P: n/a
Aha.. Another bullet point for my "Don't use unsigned unless you
really have to" armory !
Hah, no, you've gotta read the standard and familiarize yourself with
it. The more it bites the better.
Mar 19 '07 #8

P: n/a
No, the type 'unsigned' behaves as if every operation is modulo 2^bits
where 'bits' is the number of bits in the representation.
Where did ya find that, the only thing I could come up had to do with
the unary(!) - operator:

The operand of the unary - operator shall have arithmetic or enumeration
type and the result is the negation of its operand. Integral promotion
is performed on integral or enumeration operands. The negative of an
unsigned quantity is computed by subtracting its value from 2^n , where
n is the number of bits in the promoted operand. The type of the result
is the type of the promoted operand.

m - n is a binary operation.
Mar 19 '07 #9

P: n/a
On 19 Mar, 18:17, John Doe <NOTOSPAMjohndoe64...@yahoo.comwrote:
No, the type 'unsigned' behaves as if every operation is modulo 2^bits
where 'bits' is the number of bits in the representation.

Where did ya find that, the only thing I could come up had to do with
the unary(!) - operator:
Fundamental Types
3.9.1/4
Unsigned integers, declared unsigned, shall obey the laws of
arithmetic modulo 2^n where n is the number of bits in the value
representation of that particular size of integer.

and its footnote:
This implies that unsigned arithmetic does not overflow because a
result that cannot be represented by the resulting unsigned integer
type is reduced modulo the number that is one greater than the largest
value that can be represented by the resulting unsigned integer type.

The footnote talks about what happens if the result is greater than
the largest value that can be represented, but the implication is
similar for <0.

Gavin Deane

Mar 19 '07 #10

P: n/a
On 19 Mar, 18:13, John Doe <NOTOSPAMjohndoe64...@yahoo.comwrote:
Aha.. Another bullet point for my "Don't use unsigned unless you
really have to" armory !

Hah, no, you've gotta read the standard and familiarize yourself with
it. The more it bites the better.
Certainly seems to have bitten you! ... :-)

regards
Andy Little

Mar 19 '07 #11

P: n/a
and its footnote:
This implies that unsigned arithmetic does not overflow because a
result that cannot be represented by the resulting unsigned integer
type is reduced modulo the number that is one greater than the largest
value that can be represented by the resulting unsigned integer type.

The footnote talks about what happens if the result is greater than
the largest value that can be represented, but the implication is
similar for <0.
3 different places in the standard for the same thing is, I think,
still ok.
Mar 19 '07 #12

P: n/a
On Mar 19, 2:39 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
John Doe wrote:
But then again, perhaps you need to read the error message a bit more
carefully and consider *why* you're trying to find an absolute value
of an unsigned int expression...
It's you who is in error, as the difference of 2 unsigned numbers may
well be negative.

Not in C++.
Here's the line from my program:
std::abs(n - m);
where we are subtracting unsigned ints. The result may well turn
negative and what then?

I think you're mistaken. The result of any arithmetic operation between
two values of type 'unsigned' is of type 'unsigned'.

in VS 2005 , the result of difference of two shorts gave me an int :(

why?

Diego

Mar 21 '07 #13

P: n/a
"Diego Martins" <jo********@gmail.comwrote in message
news:11**********************@e1g2000hsg.googlegro ups.com...
On Mar 19, 2:39 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>John Doe wrote:
>But then again, perhaps you need to read the error message a bit more
carefully and consider *why* you're trying to find an absolute value
of an unsigned int expression...
It's you who is in error, as the difference of 2 unsigned numbers may
well be negative.

Not in C++.
Here's the line from my program:
std::abs(n - m);
where we are subtracting unsigned ints. The result may well turn
negative and what then?

I think you're mistaken. The result of any arithmetic operation between
two values of type 'unsigned' is of type 'unsigned'.


in VS 2005 , the result of difference of two shorts gave me an int :(

why?
Because both the C and C++ Standards say it should.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Mar 21 '07 #14

This discussion thread is closed

Replies have been disabled for this discussion.