Boost logo

Boost :

From: Johan Råde (rade_at_[hidden])
Date: 2008-02-25 17:23:53


Guillaume Melquiond wrote:
> Le lundi 25 février 2008 à 22:08 +0100, Johan Råde a écrit :
>>>>> I am missing the point of the changesign function. What is its
>>>>> rationale? The documentation talks about copysign(x, signbit(x) ? 1 :
>>>>> -1) but not about -x. So I am a bit lost.
>>>> Is -x guaranteed to change the sign of zero and NaN?
>>>> If it is, then I agree that the function is superfluous.
>>> Back to the topic at hand, I don't know of any architecture/compiler
>>> where negating a number does not flip the sign bit of the number, so -x
>>> works both for zero and NaN.
>> I just found out that for the ia32 architecture,
>> unary minus flips the signbit of NaN if you use the x87 units,
>> but not if you use the SSE units.
>> So the changesign function is useful.
>
> Sorry to disappoint you, but you probably have not found anything but a
> compiler optimization.
>
> As I explained in a previous mail, the sign bit is not part of the NaN
> payload. So a standard-compliant compiler is allowed to replace -NaN(17)
> by NaN(17) in the code. If you put a "volatile" between the NaN and the
> negation, you will probably get your sign back. It doesn't have anything
> to do with the arithmetic units.
>
> As a matter of fact, the SSE units do not provide any "negate" opcode,
> so compilers generate a "xor" opcode instead. You will have a hard time
> convincing anybody that the xor instruction is failing to flip the sign
> bit.
>
> So I suggest you take a look at the assembly output of your compiler and
> check what the generated code actually look like.

If I enable SSE2 on VC71 and optimize the code for speed (/O2), then

   -std::numeric_limits<double>::quiet_nan()

returns a positive NaN (binary expansion 7ff8000000000000), while

   boost::math::changesign(std::numeric_limits<double>::quiet_nan())

returns a negative NaN (binary expansion fff8000000000000).

If I turn off the compiler optimization, then both return a negative NaN.

Conclusion: boost::math::changesign is useful.

--Johan


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk