fpm
fpm copied to clipboard
Conversion between different fixed types
Hi Mike,
Thanks for the great library!
I faced an issue when trying to convert a fixed_16_16 number to a fixed<std::int64_t, __int128, 32>. In essence, it seems that the from_fixed_point function in fixed.hpp could not handle an increase number of bits for both the BaseType and the FractionBits jointly. I handled this by modifying the code as follows:
template <unsigned int NumFractionBits, typename T, typename std::enable_if<(NumFractionBits <= FractionBits)>::type* = nullptr>
static constexpr inline fixed from_fixed_point(T value) noexcept
{
T tmpT = T(1) << (FractionBits - NumFractionBits);
BaseType tmpBT = static_cast<BaseType>(value)*static_cast<BaseType>(tmpT);
return fixed(tmpBT, raw_construct_tag{});
}
This seems to do the trick, but I thought I'll mention it in case it may be of interest to others.
Cheers,
Mathieu
Hi Mathieu,
Thanks for the feedback! Looks like you've added some casts (the casting-to-types got lost I'm afraid, you may want to edit your text and use a codeblock), but I'm having trouble understanding the underlying problem that this solves. Was the compiler complaining about implicit conversions or loss of information or something?
With a BaseType of int64_t and T a long long, they are both 64-bit, so I'm not sure what the problem is.
In my case, T was a fixed_16_16 (i.e., int32_t BaseType), which I was trying to convert to an int64_t BaseType. At the same time, I was trying to increase the FractionBits from 16 to 32. The original code was computing
static_cast<BaseType>(value * (T(1) << (FractionBits - NumFractionBits)));
Unfortunately, the product before casting to BaseType could overflow. To fix it, I therefore cast both terms to BaseType before computing the product.