Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 使用基于整数除法的例程计数-是否有公式化方法?_Algorithm_Language Agnostic_Math_Puzzle - Fatal编程技术网

Algorithm 使用基于整数除法的例程计数-是否有公式化方法?

Algorithm 使用基于整数除法的例程计数-是否有公式化方法?,algorithm,language-agnostic,math,puzzle,Algorithm,Language Agnostic,Math,Puzzle,考虑一个通过连续除法和余数运算进行计数的例程 从64位被除数开始,例程除以常数除数。 如果余数为0,则例程返回。 否则,将余数乘以2^32,再加上整数商,即可生成新的红利 代码: /// ULong - 64 bit, unsigned /// UInt - 32 bit, unsigned const UInt Divisor; int TrickyCounter( ULong Dividend) { int count = 0; Ulong Quotient;

考虑一个通过连续除法和余数运算进行计数的例程

从64位被除数开始,例程除以常数除数。
如果余数为0,则例程返回。
否则,将余数乘以2^32,再加上整数商,即可生成新的红利

代码:

/// ULong - 64 bit, unsigned 
/// UInt  - 32 bit, unsigned 
const UInt Divisor; 
int TrickyCounter( ULong Dividend)
{
    int count = 0;
    Ulong Quotient;
    UInt Remainder;

    do {
        Quotient = Dividend/Divisor;
        Remainder = Dividend%Divisor;
        assert((Quotient >> 32) == 0);
        count = count + 1;
        Dividend = ((ULong)Remainder << 32) + Quotient;
    } while (Remainder != 0);
    return count;
}
///ULong-64位,无符号
///UInt-32位,无符号
常数除数;
int TrickyCounter(乌龙股息)
{
整数计数=0;
乌龙商;
单位余数;
做{
商=被除数/除数;
余数=股息%除数;
断言((商>>32)==0);
计数=计数+1;
股息=((ULong)余数0)
商=被除数/除数;
余数=股息%除数;
断言((商>>32)==0);
计数=计数-1;
股息=((ULong)余数
一些红利会导致这种循环永远持续吗


股息=0x1FFFFFL,除数=2是一个相当明显的例子,整个家族(除数)断言的确切目的是什么?另外,根据您的上一个问题,第二个代码段似乎不是您想要的。突然,有一个计数参数用于确定迭代次数,这显然使您上一个问题的答案为“否”。我为混淆道歉-最后一个文本应用于第一种形式,它没有其他退出条件。断言将商保持在2^32以下,以便有两个干净的片段合并在一起。
Uint TrickyNumber( ULong Dividend, int count)
{
    Ulong Quotient = 0;
    UInt Remainder;

    while (count > 0)
        Quotient = Dividend/Divisor;
        Remainder = Dividend%Divisor;
        assert((Quotient >> 32) == 0);
        count = count - 1;
        Dividend = ((ULong)Remainder << 32) + Quotient;
    } 
    return (UInt)Quotient;
}
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>


size_t tricky_counter( uint64_t dividend, const uint32_t divisor )
{
    const size_t cycle_buffer_size = 1024;
    size_t count = 0;
    uint64_t quotient;
    uint32_t remainder;

    uint64_t pre[cycle_buffer_size];

    do {
        pre[ count % cycle_buffer_size ] = dividend;

        quotient = dividend/divisor;
        remainder = dividend%divisor;

        if ( (quotient >> 32) != 0) {
           printf("quotient: 0x%" PRIx64 "\n", quotient);
        }

        count = count + 1;

        dividend = ((uint64_t)remainder << 32) + quotient;

        for (size_t i = 0; i < count && i<cycle_buffer_size;++i) {
            if (pre[i] == dividend) {
                size_t cycle = 0;

                printf("dividend repeats: \n");

                while (i != count % cycle_buffer_size) {
                    //~ printf("  0x%" PRIx64 " / %" PRId32 " \n", pre[i], divisor);
                    i = (i + 1) % cycle_buffer_size;
                    ++cycle;
                }

                printf("  0x%" PRIx64 " / %" PRId32 "  cycle size %zd \n", dividend, divisor, cycle);

                return 0;
            }
        }

    } while (remainder != 0);

    return count;
}


int main ( void )
{
    for (uint64_t k = 1; k < 256; ++k) 
        for (uint64_t x = 2; x < 1024; ++x) 
            tricky_counter( (x-1 << 32) + 0x01010101L * k, x);    
}