Cloud Stack Ninja

How to scale up/down integral types to other sizes, example from 8 bits to 16 bits should be:

  • 0x00 -> 0x0000
  • 0xFF -> 0xFFFF

This is what I came up with so far as a generic solution. Scale down works fine, but scale up only works if the size of the return type is two times larger than input type, 8 to 16, or 16 to 32, but not 8 to 32.

I don't know what other uses of such a function would be, other than 8 bits to 16 and vice versa. I am just tinkering with this.

#include <iostream>
#include <limits>
#include <type_traits>
#include <math.h>


template<class PxOut, class PxIn,
         typename = typename std::enable_if<std::is_integral<PxOut>::value, PxOut>::type , /// Must be integral
         typename = typename std::enable_if<std::is_integral<PxIn>::value, PxIn>::type,
         typename = typename std::enable_if<!std::is_signed<PxOut>::value, PxOut>::type , /// Must be positive
         typename = typename std::enable_if<!std::is_signed<PxIn>::value, PxOut>::type
         >

static inline constexpr PxOut binScale(PxIn x)
{

    if constexpr ( std::is_same<PxOut,PxIn>::value ){
        return x;
    }

    else if constexpr ( (/*2**/sizeof( PxIn ) ) < sizeof( PxOut ) ){
        /// ## Scale Up
        /// ## https://stackoverflow.com/a/6436100/12209845
        ///
        PxOut xx = PxIn( x );
        const uint8_t sft = sizeof( PxIn ) * 8;
        return ( ( xx + ( xx << sft ) ) << sft ) + std::numeric_limits<PxIn>::max();
    }
    else if constexpr ( sizeof( PxIn ) > sizeof( PxOut ) ){
        /// ## Scale Down
        /// ## https://code.woboq.org/qt5/qtbase/src/gui/painting/qrgba64.h.html#_ZN7QRgba647div_257Et
        ///
        const uint8_t sft = ( sizeof( PxIn ) * 8 ) - sizeof(PxOut) * 8;
        return ( x - ( x >> sft ) ) >> sft;
    }
}
/// Change the types and the test value in the next lines
///
using PxIn = uint8_t;
using PxOut =  uint16_t;
const PxIn dv = 2;


int main(int , char *[])
{
    std::cout << (uint64_t)binScale<PxOut,PxIn>(
                    (std::numeric_limits<PxIn>::max() ) /
                    dv );

    std::cout << std::endl;
    std::cout << (uint64_t)std::numeric_limits<PxOut>::max() / dv ;
    std::cout << std::endl;
    return 0;
}


Read more here: https://stackoverflow.com/questions/64400531/scale-integral-types-to-a-different-bits-size

Content Attribution

This content was originally published by User at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: