Reputation: 604
I want to implement same function for different data types of 16, 32 and 64 bits. There are fields in functions that vary depending on the input bit width. I show my implementation below. Is there any other way to realize this? You can comment on other things you see in the code as well.
uint64_t floatAngleToBinary64Angle(float fFloatAngle)
{
const float fScaleMultiplier0 = 64.0/45.0;
const float fScaleMultiplier1 = std::pow(2, 64 - 9); // 64 for 64bits
return ((uint64_t)(fFloatAngle * fScaleMultiplier0 * fScaleMultiplier1));
}
uint32_t floatAngleToBinary32Angle(float fFloatAngle)
{
const float fScaleMultiplier0 = 64.0/45.0;
const float fScaleMultiplier1 = std::pow(2, 32 - 9); // 32 for 32bits
return ((uint32_t)(fFloatAngle * fScaleMultiplier0 * fScaleMultiplier1));
}
uint16_t floatAngleToBinary16Angle(float fFloatAngle)
{
const float fScaleMultiplier0 = 64.0/45.0;
const float fScaleMultiplier1 = std::pow(2, 16 - 9); // 16 for 16bits
return ((uint16_t)(fFloatAngle * fScaleMultiplier0 * fScaleMultiplier1));
}
Upvotes: 3
Views: 616
Reputation: 18368
More compact suggestion:
#include <type_traits>
template <typename T>
T floatAngleToBinary(float fFloatAngle)
{
static_assert(std::is_same<uint64_t,T>() || std::is_same<uint32_t,T>() || std::is_same<uint16_t,T>(),"unsupported type");
const float fScaleMultiplier0 = 64.0/45.0;
const float fScaleMultiplier1 = std::pow(2, sizeof(T) * 8 - 9);
return ((T)(fFloatAngle * fScaleMultiplier0 * fScaleMultiplier1));
}
Execution examples for different types:
uint64_t a = floatAngleToBinary<uint64_t>(fFloatAngle);
return floatAngleToBinary<uint32_t>(fFloatAngle);
uint16_t b = 5 + floatAngleToBinary<uint16_t>(fFloatAngle);
Upvotes: 2
Reputation: 63154
You can't overload functions on their return type alone, but you can return an object which defers the calculation to when the destination type is known:
auto floatAngleToBinaryAngle(float fFloatAngle) {
struct converter {
float fFloatAngle;
operator uint64_t () const
{
const float fScaleMultiplier0 = 64.0/45.0;
const float fScaleMultiplier1 = std::pow(2, 64 - 9); // 64 for 64bits
return ((uint64_t)(fFloatAngle * fScaleMultiplier0 * fScaleMultiplier1));
}
operator uint32_t () const
{
const float fScaleMultiplier0 = 64.0/45.0;
const float fScaleMultiplier1 = std::pow(2, 32 - 9); // 32 for 32bits
return ((uint32_t)(fFloatAngle * fScaleMultiplier0 * fScaleMultiplier1));
}
operator uint16_t () const
{
const float fScaleMultiplier0 = 64.0/45.0;
const float fScaleMultiplier1 = std::pow(2, 16 - 9); // 16 for 16bits
return ((uint16_t)(fFloatAngle * fScaleMultiplier0 * fScaleMultiplier1));
}
};
return converter{fFloatAngle};
}
// Usage
uint32_t angle = floatAngleToBinaryAngle(2.1f);
Upvotes: 2
Reputation: 2699
You can't overload return types, but you can reuse the implementation with a template function:
template <typename T>
T floatAngleImpl(float fFloatAngle)
{
const float fScaleMultiplier0 = 64.0/45.0;
const float fScaleMultiplier1 = std::pow(2, sizeof(T)*8 - 9); // number of bits in type T
return ((T)(fFloatAngle * fScaleMultiplier0 * fScaleMultiplier1));
}
uint64_t floatAngleToBinary64Angle(float fFloatAngle)
{
return floatAngleImpl<uint64_t>(fFloatAngle);
}
uint32_t floatAngleToBinary32Angle(float fFloatAngle)
{
return floatAngleImpl<uint32_t>(fFloatAngle);
}
uint16_t floatAngleToBinary16Angle(float fFloatAngle)
{
return floatAngleImpl<uint16_t>(fFloatAngle);
}
Upvotes: 9
Reputation: 60402
You can't overload functions on the return type. One option is to have the differing type as an argument, e.g.
void floatAngleToBinary64Angle(uint64_t &ans, float fFloatAngle)
{
// ...
ans = ...
}
and then you can call your function like this:
unit64_t a;
floatAngleToBinary64Angle(a, 4.2);
Upvotes: 1