0

I have discovered boost::math::changesign function, but cannot find a rationale of using it. The Internet keeps radio silence and even Boost itself barely uses it.

My thoughts were:

  1. There are some values where -x is forbidden.
  2. To avoid compiler bugs.
  3. Faster at runtime.

However:

  1. It seems to be a valid operation on any value, at least for IEEE 754.
  2. The different compilers/platforms I have tried generate bit-identical results for changesign and -x https://godbolt.org/g/4ttsfW.
  3. Current GCC and Clang produces the same machine codes for both methods, the older ones (and any MSVC) generate a way longer assembly for changesign https://godbolt.org/g/nT6j26.
Nikita Kniazev
  • 3,728
  • 2
  • 16
  • 30
  • 1
    From the link: _"For finite values, this function has the same effect as simple negation, the assignment z = -z, but for nonfinite values, infinities and NaNs, the changesign(x) function may be the only portable way to ensure that the sign bit is changed."_ – Richard Critten Jul 28 '18 at 19:31
  • That statement has no citations and says "may be", so it "may be" wrong. – Nikita Kniazev Jul 28 '18 at 19:51
  • 2
    It says “may be” because C++ allows implementations to have somewhat different behaviors regarding special values. In one implementation `-x` might always work if `x` is a NaN. In such an implementation, `changesign` is not the only way to ensure the sign bit is changed. In another implementation, `-x` might trap if `x` is a NaN (or a certain NaN). In such an implementation, `changesign` is the only way to ensure the sign bit is changed. So “may be” is qualifying different behaviors of C++ implementations, not telling you `changesign` might or might not have this rationale for its existence. – Eric Postpischil Jul 28 '18 at 19:58
  • @NikitaKniazev I posted that quote because I think you should have included that information in the question, given that it was written by the package maintainers. It would have made the question clearer. – Richard Critten Jul 28 '18 at 22:01

1 Answers1

1

boost::math::changesign effectively works on its operand a bit level: It changes the sign bit and is not affected by other aspects of the operand. This differs from the unary - operator because the unary - operator is mathematical and may be affected by values that are NaNs (for example, it may trap if the input is a NaN). Whether the - operator is affected by such things is implementation-dependent, whereas boost::math::changesign is intended to change the sign regardless of the C++ implementation.

  1. Is irrelevant because the C++ unary - operator is not bound to the negate operation in IEEE 754-2008. In other words, C++ says it has a unary - operator and describes some of its behavior, and IEEE 754 has a negate operation that reverses the sign bit, but the C++ standard does not require that the unary - operator perform the IEEE 754 negate operation. Additionally, the link in the question goes to a question that is answered with caveats that confirm C++’s unary - might not function as the IEEE 754 negate.

  2. and 3. show a set of points in the set of possible implementations of C++ (or set of possible approximate implementations of C++) and do not speak to the existence or non-existence of other implementations of C++ that behave differently.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312