3

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));
}

3
  • You can't overload functions on return-type in c++ Commented Apr 21, 2020 at 15:12
  • No, you can't overload on return types. Commented Apr 21, 2020 at 15:12
  • 1
    @melk: Except for template functions, (that indeed doesn't apply to OP's case). Commented Apr 21, 2020 at 15:30

4 Answers 4

9

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);
}
Sign up to request clarification or add additional context in comments.

Comments

2

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);

Comments

2

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);

Comments

1

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.