Калькулятор только с конкретными методами.Нормальный и рекурсивный - PullRequest
0 голосов
/ 25 июня 2018

Итак, я застрял с моим калькулятором. Разрешается использовать только следующие методы:

int succ(int x){
    return ++x;
}



int neg(int x){
    return -x;
}

То, что я уже получил, это +, -. *. Итератив также рекурсивен (так что я также могу использовать их при необходимости). Теперь я застрял на методе деления, потому что я не знаю, как обращаться с запятыми и логикой, стоящей за ними. Просто представьте, как выглядит succ () и neg (), вот пример итеративного и рекурсивного вычитания:

int sub(int x, int y){
    if (y > 0){
        y = neg(y);
        x = add(x, y);
        return x;
    }
    else if (y < 0){
        y = neg(y);
        x = add(x, y);
        return x;
    }
    else if (y == 0) {
        return x;
    }
   }

int sub_recc(int x, int y){
    if (y < 0){
        y = neg(y);
        x = add_recc(x, y);
        return x;
    } else if (y > 0){
        x = sub_recc(x, y - 1); 
        x = x - 1;
        return x;
    }else if( y == 0) {
        return x;
    }
}

1 Ответ

0 голосов
/ 25 июня 2018

Если вы можете вычесть и сложить, то вы можете обрабатывать целочисленное деление.В псевдокоде это просто:

division y/x is:
   First handle signs because we will only divide positive integers
   set sign = 0
   if y > 0 then y = neg(y), sign = 1 - sign
   if x > 0 then y = neg(y), sign = 1 - sign
   ok, if sign is 0 nothing to do, if sign is 1, we will negate the result

   Now the quotient is just the number of times you can substract the divisor:
   set quotient = 0
   while y > x do
       y = y - x
       quotient = quotient + 1
   Ok we have the absolute value of the quotient, now for the sign:
   if sign == 1, then quotient = neg(quotient)

Правильный перевод на языке C ++, а также рекурсивная часть оставлены в качестве упражнения ...

Подсказка для рекурсии y / x ==1 + (yx) / x, а y> x


Выше была целая часть.Целое число приятно и просто, потому что оно дает точные операции.Представление с плавающей точкой в ​​ base всегда является чем-то близким к мантиссе * base exp , где mantissa - это либо целое число с максимальным количеством цифр, либо число от 0 до 1 (сказанонормальное представление).И вы можете переходить от одного представления к другому, но изменяя экспонентную часть на количество цифр мантиссы: 2,5 - это 25 10 -1 (int mantissa) .25 10 1 (0 <= mantissa <1). </p>

Итак, если вы хотите использовать числа с плавающей запятой 10, вам следует:

  • преобразовать целое число в число с плавающей запятой (mantissa + exponent) представление
  • для сложения и вычитания, показатель степени результата равен a priori наибольшему из показателей степени.Обе мантиссы должны быть масштабированы до этого показателя и добавлены / вычтены.Затем необходимо скорректировать окончательный показатель, потому что операция могла добавить дополнительную цифру (7 + 9 = 16) или привела к исчезновению единиц высшего порядка (101 - 98 - 3)
  • для продукта, добавляемого вами.экспоненты и умножьте мантиссы, а затем нормализуйте (откорректируйте экспоненту) результат
  • для деления, вы масштабируете мантиссу на максимальное количество цифр, делаете деление с помощью алгоритма целочисленного деленияи снова нормализуем.Например, 1/3 с точностью до 6 цифр получается с: 1/3 = (1 * 10 6 / 3) * 10 -6 = (1000000/3) *10 -6

это дает 333333 * 10 -6 так что .333333 в нормализованном виде

Хорошо, это будет многокода кипящей тарелки, но ничего сложного.

Краткий рассказ: просто вспомните, как вы узнали это с бумагой и карандашом ...

...