chsvlib
chsv helper source code

◆ to_signed()

constexpr auto Chusov::to_signed ( val)
constexpr

Attempts to converts an integral to its signed form without losing information and throws an exception, if that is not possible.

Template Parameters
TA type of the value to convert.
Parameters
valA value to convert to the signed form.
Returns
A signed value equal to val.

The function template is only defined for integral T, otherwise there is substitution failure.

If T is already signed, the function performs no action.

If T is unsigned, and the signed arithmetic on the target machine is implemented as two's complement, and bit sizes of signed and unsigned forms of T are equal, the function makes a static conversion and is marked noexcept.

Otherwise, the function tries to fit the value into the destination type at runtime as follows.

  • If \(\forall x: 0 \le x \le M\), where M = std::numeric_limits<std::make_signed<T>>::max() > 0 is the maximal value that can be represented with the signed type associated with the unsigned T, then signed and unsigned representations of \(x\) are equivalent. That is, if val <= M, the function yields the signed value equal to val.
  • \(\forall x: n + m \le x < n\), where m = std::numeric_limits<std::make_signed<T>>::min() < 0 is the minimal value that can be represented with the signed type, and n = std::numeric_limits<T>::max() + 1 is a number of elements within the additive group \(\mathbb{Z}_n\) represented by the unsigned type T, the value produced by the function is congruent to \((x - (n + m)) + m\) in the additive group \(\{m,\dots, M\}\). Therefore, if val >= n + m, the function yields the signed value (val - (n + m)) + m.
  • In all other cases, i.e. \(\forall x: M < x < n + m\) the function fails throwing ArithmeticOverflowException.