5

I tried using std::copysign to set an int with the sign of another.

int translate = getTranslate();
int offset = getOffset();
translate = std::copysign(offset, translate)

But copysign<int, int> returns a double. How should I use it better? Or what should I use instead?

The Shmoo
  • 358
  • 1
  • 16
  • 1
    Is [`std::copysign`](https://en.cppreference.com/w/cpp/numeric/math/copysign) really the function you want to use here? It "[c]omposes a floating point value with the magnitude of x and the sign of y", is that really what you want to do? – Some programmer dude Oct 21 '19 at 09:08
  • Thanks for your quick response! I am looking for an alternative to use the sign of `offset` for `translate`. – The Shmoo Oct 21 '19 at 09:10
  • 3
    So basically something similar to `translate = (offset < 0 ? -std:abs(translate) : std::abs(translate))`? – Some programmer dude Oct 21 '19 at 09:13
  • 3
    @Someprogrammerdude That's wrong if `translate` is negative. You need `std::abs(translate)` in the second and third ternary operator arguments. – Max Langhof Oct 21 '19 at 09:13
  • @MaxLanghof Ah yes of course, "fixed" my comment. Thanks :) – Some programmer dude Oct 21 '19 at 09:16
  • Thanks for the alternative! This is also nice to wrap into a template function. The marked answer is a good explanation why there is no `copysign` for `int`! – The Shmoo Oct 21 '19 at 09:22

1 Answers1

5

At first I was a bit confused about what std::copysign is actually good for, but the note on cppreference gives a reasonable motivation:

std::copysign is the only portable way to manipulate the sign of a NaN value (to examine the sign of a NaN, signbit may also be used)

Take this plus the fact that integers cannot be NaN and it makes sense that there is no std::copysign for int. On the other hand, a std::copysign<int,int> returning an int would come in handy in generic code, where you want it to work for double as well as for int. For this I would perhaps write my own wrapper, starting from a

template <typename T> 
T my_copy_sign(const T& t, const T& s);

and then specialize it accordingly.

PS: If you are only working on int, you probably dont need std::copysign in the first place.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • Thanks a lot! This is a great explanation and makes sense. I also like that you understood why I need it and why it would be convenient for generic code. – The Shmoo Oct 21 '19 at 09:23