divide_infinity.hpp

Back to Bit operations

pastel/sys/math/

#ifndef PASTELSYS_DIVIDE_INFINITY_HPP
#define PASTELSYS_DIVIDE_INFINITY_HPP

#include "pastel/sys/math/divide_infinity.h"
#include "pastel/sys/ensure.h"

namespace Pastel
{

    template <
        typename Integer,
        typename N_Integer,
        Requires<
            Models<Integer, Integer_Concept>,
            Models<N_Integer, Integer_Concept>
        >
    >
    Integer divideInfinity(const N_Integer& n)
    {
        PENSURE_OP(n, >=, 2);

        // Let w = SizeInBits<uinteger>::value.

        if (negative(Integer(1)))
        {
            // The number is 2-bit signed;
            // the result is zero.
            return Integer(0);
        }

        if (odd(n))
        {
            // Suppose n is odd. Then n does not divide 2^w. 
            // Therefore there exists a, b in NN 
            // such that
            //
            //     2^w = a n + b, 0 < b < n
            //     <=>
            //     2^w - 1 = a n + (b - 1),  0 <= b - 1 < n - 1 < n.
            //
            // Therefore 
            //
            //     floor(2^w / n) = a = floor((2^w - 1) / n).

            return (Integer)Infinity() / n;
        }

        // Suppose n is even. Then
        // 
        //     floor(2^w / n)
        //   = floor(2^{w - 1} / (n / 2))
        //   = floor([floor((2^w - 1) / 2) + 1] / (n / 2))

        return (((Integer)Infinity() >> 1) + 1) / (n >> 1);
    }

}

#endif