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