0


1

逐次除算w /剰余演算によってカウントするルーチンを考えてみましょう。

64ビットの被除数から始めて、ルーチンは定数の除数で除算します。 剰余が0の場合、ルーチンは戻ります。 そうでなければ、新しい被除数は剰余に2 ^ 32を掛けて整数の商を加えることによって構築されます。

コードでは:

/// ULong - 64 bit, unsigned
/// UInt  - 32 bit, unsigned
const UInt除数。 int TrickyCounter(超長期配当){int count = 0; Ulong Quotient; UIntの残り

do {商=配当/除数;剰余=除算%除数。 assert((Quotient >> 32)== 0);カウント=カウント1。配当=((ULong)余り<< 32)商; while(剰余!= 0);戻りカウント}

任意の除数で、望ましいカウントを得るために必要なDividendを計算するためのできれば非反復的な方法はありますか? 多くの初期配当にとって、これはすぐに「アサート」状態に陥るようです。 いくつかの配当はこれを永久にループさせるでしょうか?

'' '' '

もしカウントの代わりに、ルーチンが商を返すなら、私は返されるほしい数を生成するためにDividendを計算することができますか?

Uint TrickyNumber(ULong配当、intカウント){Ulong商= 0; UIntの残り

while(count> 0)商=配当/除数。剰余=除算%除数。 assert((Quotient >> 32)== 0); count = count  -  1;配当=((ULong)余り<< 32)商;戻り値(UInt)商。 }

1 Answer


1


_ いくつかの配当はこれを永久にループさせるでしょうか? _

Dividend = 0x1ffffffffL、Divisor = 2はかなり明白な例で、家族全員(Divisor << 32)-1、Divisorは固定小数点です。

これらから作業して、初期の配当と除数の多くの循環的な組み合わせが見つかります、そして私はもっとあると確信しています:

#include
#include
#include


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