Как правильно реализовать `operator /`? - PullRequest
0 голосов
/ 17 июня 2011

ОСНОВНОЕ РЕДАКТИРОВАНИЕ: Может кто-нибудь объяснить мне, как исправить оператора / чтобы он работал правильно?я понимаю, что сдвиг не всегда корректен, например, для 10 / 3, что приведет к бесконечным циклам.так как я могу это исправить?

весь код на http://ideone.com/GhF0e

uint128_t operator/(uint128_t rhs){
    // Save some calculations ///////////////////////
    if (rhs == 0){
        std::cout << "Error: division or modulus by zero" << std::endl;
        exit(1);
    }
    if (rhs == 1)
        return *this;
    if (*this == rhs)
        return uint128_t(1);
    if ((*this == 0) | (*this < rhs))
        return uint128_t(0, 0);
    // //////////////////////////////////////////////
    uint128_t copyn(*this), quotient = 0;
    while (copyn >= rhs){
        uint128_t copyd(rhs), temp(1);
        // shift the divosr to match the highest bit
        while (copyn > (copyd << 1)){
            copyd <<= 1;
            temp <<= 1;
        }
        copyn -= copyd;
        quotient += temp;
    }
    return quotient;
}

это правильно?

    uint128_t operator/(uint128_t rhs){
        // Save some calculations ///////////////////////
        if (rhs == 0){
            std::cout << "Error: division or modulus by zero" << std::endl;
            exit(1);
        }
        if (rhs == 1)
            return *this;
        if (*this == rhs)
            return uint128_t(1);
        if ((*this == 0) | (*this < rhs))
            return uint128_t(0);
        uint128_t copyd(rhs);
        // Checks for divisors that are powers of two
        uint8_t s = 0;
        while ((copyd.LOWER & 1) == 0){
            copyd >>= 1;
            s++;
        }
        if (copyd == 1)
            return *this >> s;
        // //////////////////////////////////////////////

        uint128_t copyn(*this), quotient = 0;
        copyd = rhs;
        uint8_t n_b = 255, d_b = 0;
        while (copyd){
            copyd >>= 1;
            d_b++;// bit size of denomiator
        }
        copyd = rhs;
        while (n_b > d_b){
            // get the highest bit of dividend at current step
            n_b = 0;
            uint128_t copycopyn(copyn);
            while (copycopyn){
                copycopyn >>= 1;
                n_b++;
            }
            uint8_t highest_bit = n_b - d_b - 1;
            copyn -= copyd << highest_bit;
            quotient += uint128_t(1) << highest_bit;
        }
        if (n_b == d_b)
            quotient++;
        return quotient;
    }

кажется, что это правильно, кромеЯ каким-то образом получаю случайные большие значения при моддинге на 10, хотя моя функция мода просто

    uint128_t operator%(uint128_t rhs){
        return *this - (rhs * (*this / rhs));
    }

Ответы [ 4 ]

2 голосов
/ 17 июня 2011

В выражении «copyn> (copyd << 1)» «copyd << 1» может переполниться, что приведет к бесконечному циклу, который вы наблюдаете. Я бы предложил проверить наличие переполнения или сделать проверку более похожей на «(copyn >> n)> copyd».

2 голосов
/ 17 июня 2011

Что по этому поводу:

int div;  // Uninitialized variable.

Что произойдет, если все тесты в потоке не пройдены.
Тогда div может иметь любое значение. Если это 0 (или 1), тогда rhs никогда не достигнет 0.

0 голосов
/ 17 июня 2011

Я не уверен, что это проблема, но это выглядит так:

stream << out;
return stream;

Находится вне функции, в области видимости класса.

Вы, вероятно, хотите избавиться от одного из } s после else.

0 голосов
/ 17 июня 2011

Если бы был бесконечный цикл, вы бы даже не смогли вывести -1.-1 не такой маленький, как -123455, но вы должны попробовать.С оператором << нет ничего плохого, но что-то не так с вашим предположением об операторе /.Там тоже что-то не так, но я не уверен, стоит ли мне делать домашнее задание ^ _ ^ </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...