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

Sign of a number ...

P: n/a
Hi,

a simple question:

Which standard function in c++ gives me the sign of a number?

Thanks
Konrad
Nov 14 '07 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Konrad Mühler wrote:
a simple question:

Which standard function in c++ gives me the sign of a number?
There is no standard function in C++ (mostly because there is no
agreement on what such function would return for 0, for example).
Why do you ask? Is it difficult to write? Are you concerned
with performance?

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

P: n/a
Konrad Mühler wrote:
Hi,

a simple question:

Which standard function in c++ gives me the sign of a number?
In addition to what Victor said...

There's always std::less<>().
Nov 14 '07 #3

P: n/a
On Nov 14, 4:14 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Konrad Mühler wrote:
a simple question:
Which standard function in c++ gives me the sign of a number?

There is no standard function in C++ (mostly because there is no
agreement on what such function would return for 0, for example).
Why do you ask? Is it difficult to write? Are you concerned
with performance?

You can do it with bits field:

#include <iostream>

template <typename T>
struct Sign
{
bool S:1;
T Remaining:(sizeof(T)-1);
};

int main()
{
Sign<intz;
int zero = 0;
int minusone = -1;
float minuszero = -0.0;
memcpy(&z,&zero,sizeof(zero));
std::cout << z.S << std::endl;
memcpy(&z,&minusone,sizeof(minusone));
std::cout << z.S << std::endl;

Sign<intzz;
memcpy(&zz,&minuszero,sizeof(minuszero));
std::cout << z.S << std::endl;
return 0;
}

In which case 0 and -0 are different, this will not be compatible with
a solution using '<' and/or '>'

HTH
-Mathieu

Nov 14 '07 #4

P: n/a
mathieu wrote:
You can do it with bits field:

#include <iostream>

template <typename T>
struct Sign
{
bool S:1;
T Remaining:(sizeof(T)-1);
};

int main()
{
Sign<intz;
int zero = 0;
int minusone = -1;
float minuszero = -0.0;
memcpy(&z,&zero,sizeof(zero));
std::cout << z.S << std::endl;
memcpy(&z,&minusone,sizeof(minusone));
std::cout << z.S << std::endl;

Sign<intzz;
memcpy(&zz,&minuszero,sizeof(minuszero));
std::cout << z.S << std::endl;
return 0;
}

In which case 0 and -0 are different, this will not be compatible with
a solution using '<' and/or '>'
I doubt that any of this is guaranteed to work, and even if it is, it's
horrible code. What's wrong with 'if (val>0.0)'?

--
Philip Potter pgp <atdoc.ic.ac.uk
Nov 14 '07 #5

P: n/a
mathieu wrote:
On Nov 14, 4:14 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>Konrad Mühler wrote:
>>a simple question:
>>Which standard function in c++ gives me the sign of a number?

There is no standard function in C++ (mostly because there is no
agreement on what such function would return for 0, for example).
Why do you ask? Is it difficult to write? Are you concerned
with performance?


You can do it with bits field:
Why are you replying to me? If I were to do it, I'd simply write

template<class Tint sign(T t) {
return t < 0 ? -1 : t 0 ? 1 : 0;
}

but that's just one definition of 'sign' (another treats 0 as
a positive value). Besides, the OP may want to return T instead
of 'int'...
>
#include <iostream>

template <typename T>
struct Sign
{
bool S:1;
T Remaining:(sizeof(T)-1);
'sizeof' does NOT return the number of bits in the object...
};

int main()
{
Sign<intz;
int zero = 0;
int minusone = -1;
float minuszero = -0.0;
memcpy(&z,&zero,sizeof(zero));
std::cout << z.S << std::endl;
memcpy(&z,&minusone,sizeof(minusone));
std::cout << z.S << std::endl;

Sign<intzz;
memcpy(&zz,&minuszero,sizeof(minuszero));
std::cout << z.S << std::endl;
return 0;
}

In which case 0 and -0 are different, this will not be compatible with
a solution using '<' and/or '>'

HTH
'fraid it don't. Have you actually tested your program before posting?
-Mathieu
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 14 '07 #6

P: n/a
On Nov 14, 5:51 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
mathieu wrote:
On Nov 14, 4:14 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Konrad Mühler wrote:
a simple question:
>Which standard function in c++ gives me the sign of a number?
There is no standard function in C++ (mostly because there is no
agreement on what such function would return for 0, for example).
Why do you ask? Is it difficult to write? Are you concerned
with performance?
You can do it with bits field:

Why are you replying to me?
my bad, sorry.
#include <iostream>
template <typename T>
struct Sign
{
bool S:1;
T Remaining:(sizeof(T)-1);

'sizeof' does NOT return the number of bits in the object...
ooops...
>
};
int main()
{
Sign<intz;
int zero = 0;
int minusone = -1;
float minuszero = -0.0;
memcpy(&z,&zero,sizeof(zero));
std::cout << z.S << std::endl;
memcpy(&z,&minusone,sizeof(minusone));
std::cout << z.S << std::endl;
Sign<intzz;
memcpy(&zz,&minuszero,sizeof(minuszero));
std::cout << z.S << std::endl;
return 0;
}
In which case 0 and -0 are different, this will not be compatible with
a solution using '<' and/or '>'
HTH

'fraid it don't. Have you actually tested your program before posting?
I meant to say that

if ( t < 0 ) return 0;
else return 1;

is not compatible with the bit fields solution...

and indeed I did test my solution before posting:

$ gcc --version
gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

-Mathieu

Nov 14 '07 #7

P: n/a
mathieu wrote:
[..]
I meant to say that

if ( t < 0 ) return 0;
else return 1;

is not compatible with the bit fields solution...
It's not "compatible" with any known 'sign' definitions either.
I am still unsure why you'd need to create some bitfield monster
when a simple stand-alone function would do...

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

P: n/a
Victor Bazarov wrote:
mathieu wrote:
>[..]
I meant to say that

if ( t < 0 ) return 0;
else return 1;

is not compatible with the bit fields solution...

It's not "compatible" with any known 'sign' definitions either.
I am still unsure why you'd need to create some bitfield monster
when a simple stand-alone function would do...
I believe what he's trying to do is read the floating-point sign bit and
return that. This distinguishes between positive and negative zero, but
that distinction is not always useful.

--
Philip Potter pgp <atdoc.ic.ac.uk
Nov 14 '07 #9

P: n/a
Hi

Konrad Mühler wrote:
Which standard function in c++ gives me the sign of a number?
Assuming that you have a compiler that supports the C99-library, there
is "int signbit (X)" in math.h.

From the manpage:
‘signbit’ is a generic macro which can work on all real floating-point
types. It returns a non-zero value if the value of X has its sign bit
set.
This is not the same as ‘x < 0.0’, because IEEE 754 floating point
allows zero to be signed. The comparison ‘-0.0 < 0.0’ is false, but
‘signbit (-0.0)’ will return a non-zero value.

Markus

Nov 15 '07 #10

P: n/a
Markus Moll wrote:
Konrad Mühler wrote:
>Which standard function in c++ gives me the sign of a number?

Assuming that you have a compiler that supports the C99-library, there
is "int signbit (X)" in math.h.

From the manpage:
'signbit' is a generic macro which can work on all real
floating-point types. It returns a non-zero value if the value of X
has its sign bit set.
This is not the same as 'x < 0.0', because IEEE 754 floating
point allows zero to be signed. The comparison '-0.0 < 0.0' is
false, but 'signbit (-0.0)' will return a non-zero value.
Are you saying that the 'sgn' function in Mathematica is equivalent
to this 'signbit'? Or 'Sgn' function in VB is? I beg to differ.
BTW, does the negative zero compare equal to [the positive] zero?

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

P: n/a
On Nov 15, 4:37 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Markus Moll wrote:
Konrad Mühler wrote:
Which standard function in c++ gives me the sign of a number?
Assuming that you have a compiler that supports the C99-library, there
is "int signbit (X)" in math.h.
From the manpage:
'signbit' is a generic macro which can work on all real
floating-point types. It returns a non-zero value if the value of X
has its sign bit set.
This is not the same as 'x < 0.0', because IEEE 754 floating
point allows zero to be signed. The comparison '-0.0 < 0.0' is
false, but 'signbit (-0.0)' will return a non-zero value.
Are you saying that the 'sgn' function in Mathematica is equivalent
to this 'signbit'? Or 'Sgn' function in VB is?
I don't know about those, but the sign function in Fortran
returned -1, 0 or 1, and returned 0 for both plus and minus 0
(like the function you proposed).
I beg to differ.
BTW, does the negative zero compare equal to [the positive] zero?
Yes, by law (i.e. the C and the C++ standards). In practice,
there are very few ways you can distinguish between the two:
1/-0.0 returns -Inf, whereas 1/+0.0 returns +Inf (and I think
you can compare [+-]Inf with 0.0, so if you had a zero, and
wanted to know its sign, you could do "if ( 1/zero < 0.0 )", or
something like that).

I'm not a specialist in numerical analysis, so I'm probably
putting my foot in my mouth, but about the only time I can see
the sign bit being useful is when outputting to a binary format.
A truely portable output would use signbit(), ldexp() and
frexp() to extract the sign, the exponent and the mantissa
separately, then recombine them according to the requirements of
the format. Something like:

oxdrstream&
oxdrstream::operator<<(
float source )
{
BytePutter dest( *this ) ;
bool isNeg = signbit( source ) ;
if ( isNeg ) {
source = - source ;
}
int exp ;
if ( source == 0.0 ) {
exp = 0 ;
} else {
source = ldexp( frexp( source, &exp ), 24 ) ;
exp += 126 ;
}
uint32_t mant = source ;
dest.put( (isNeg ? 0x80 : 0x00) | exp >1 ) ;
dest.put( ((exp << 7) & 0x80) | ((mant >16) & 0x7F) ) ;
dest.put( mant >8 ) ;
dest.put( mant ) ;
return *this ;
}

If you know you've got IEEE internally, of course, you can just
memcpy into a uint32_t, and output that as you would an unsigned
int. (Surprisingly, however, at least on a Sun Sparc, the above
is not outrageously slow.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nov 16 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.