как сохранить xmldocument в поток

Процедура деления целых чисел, которая использует сдвиги и добавления, может быть получена простым способом из десятичного деления на длинные руки, как учили в начальной школе. Выбор каждой условной цифры упрощается, так как цифра равна 0 и 1: если текущий остаток больше или равен делителю, младший значащий бит частичного частного равен 1.

Просто как и с децимальным делением на длинные руки, цифры дивиденда считаются от наиболее значимых до наименее значимых, по одной цифре за раз. Это легко осуществить левым сдвигом в двоичном делении. Кроме того, частные биты собираются левым смещением текущих битов отношения на одну позицию, а затем добавлением нового бит частного.

В классическом расположении эти два сдвига влево объединены в левое смещение одной пары регистров. Верхняя половина удерживает текущий остаток, нижняя половина начинается с дивиденда. Поскольку биты дивидендов передаются в регистр остатка по левому сдвигу, неиспользуемые младшие значащие разряды нижней половины используются для накопления частных битов.

Ниже приведен язык ассемблера x86 и реализации C этого алгоритма. Этот конкретный вариант сдвига & amp; добавление деления иногда упоминается как «невыполняющий» вариант, так как вычитание делителя из текущего остатка не выполняется, если остаток больше или равен делителю. В C нет понятия флага переноса, используемого версией сборки в левом сдвиге пары регистров. Вместо этого он эмулируется, основываясь на наблюдении, что результат добавления по модулю 2n может быть меньшим, чем либо добавляться только в случае выполнения.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define USE_ASM 0

#if USE_ASM
uint32_t bitwise_division (uint32_t dividend, uint32_t divisor)
{
    uint32_t quot;
    __asm {
        mov  eax, [dividend];// quot = dividend
        mov  ecx, [divisor]; // divisor
        mov  edx, 32;        // bits_left
        mov  ebx, 0;         // rem
    $div_loop:
        add  eax, eax;       // (rem:quot) << 1
        adc  ebx, ebx;       //  ...
        cmp  ebx, ecx;       // rem >= divisor ?
        jb  $quot_bit_is_0;  // if (rem < divisor)
    $quot_bit_is_1:          // 
        sub  ebx, ecx;       // rem = rem - divisor
        add  eax, 1;         // quot++
    $quot_bit_is_0:
        dec  edx;            // bits_left--
        jnz  $div_loop;      // while (bits_left)
        mov  [quot], eax;    // quot
    }            
    return quot;
}
#else
uint32_t bitwise_division (uint32_t dividend, uint32_t divisor)
{
    uint32_t quot, rem, t;
    int bits_left = CHAR_BIT * sizeof (uint32_t);

    quot = dividend;
    rem = 0;
    do {
            // (rem:quot) << 1
            t = quot;
            quot = quot + quot;
            rem = rem + rem + (quot < t);

            if (rem >= divisor) {
                rem = rem - divisor;
                quot = quot + 1;
            }
            bits_left--;
    } while (bits_left);
    return quot;
}
#endif
13
задан Kit 17 January 2017 в 20:56
поделиться