Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++] Функция возведения в степень, для больших чисел 
V
    Опции темы
Kernigan
Дата 18.6.2006, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 18.6.2006

Репутация: нет
Всего: нет



Требуется написать функцию, на C++, возведения в степень y основания x, где x, y - тип класса, например, MyClass pow (MyClass & x, MyClass & y). Если кто-то уже сталкивался с подобной задачей, прошу откликнуться. 
PM MAIL   Вверх
MAKCim
Дата 18.6.2006, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



реализуй умножение больших чисел (возьми исходник) 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Kernigan
Дата 18.6.2006, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 18.6.2006

Репутация: нет
Всего: нет



В инете я нашёл несколько исходников, но ничего конкретного. Если у вас MAKCim есть ссылка что-то похожее, укажите пожалуйста. 
PM MAIL   Вверх
MAKCim
Дата 18.6.2006, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Код

template<class T> 
    class long_number
{
public:
    typedef T char_t;
private:
    std::vector<char_t> number_;
public:
    long_number<T>& operator*=(const long_number<T>&);

    long_number<T>& operator--();

    bool operator>(long);
};

template<class T> long_number<T> operator^
    (const long_number<T>& obj_a, const long_number<T> obj_b)
{
    long_number<T> obj=obj_a, deg=obj_b;
    while (--deg>0) obj*=obj_a;
    return obj;
}

реализуй операции operator*=, --, > 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Kernigan
Дата 21.6.2006, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 18.6.2006

Репутация: нет
Всего: нет



Благодарю MAKSim'а за предоставленный код 
PM MAIL   Вверх
En_t_end
Дата 26.1.2007, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 2
Всего: 20



MAKCim, 
А ускорить процесс возведения в степень можно как-то ?
PM MAIL ICQ Skype GTalk Jabber   Вверх
V.A.KeRneL
  Дата 27.1.2007, 10:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vadim A. Kazantsev
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 3.12.2006
Где: Moscow, Russia

Репутация: 7
Всего: 14



Цитата(En_t_end @  26.1.2007, 18:42 Найти цитируемый пост)

MAKCim, 
А ускорить процесс возведения в степень можно как-то ?


En_t_end, а можно я отвечу? Ну, пожалуйста! smile

Из книжки Ксиены и Ревиллы: 
«* Возведение в степень. Возведение в степень — это повторяемое умножение, так что тут возникают те же проблемы с производительностью, что и при многократном сложении длинных чисел. Хитрость состоит в том, чтобы заметить, что 
Код

a^n = a^(n div 2) * a^(n div 2) * a^(n mod 2)

, так что можно обойтись, используя только логарифмическое число умножений.»



--------------------
«C'est un pense-creux d'ici. C'est le meilleur et le plus irascible homme du monde...» © Ф.М. Достоевский, «Бесы»
---/)/)---(\.../)---(\(\
--(':'=)---(=';'=)---(=':')
(")(")..)-(").--.(")-(..(")(")

PM MAIL IM ICQ AOL YIM MSN   Вверх
sergejzr
Дата 27.1.2007, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 11
Всего: 360



Цитата(V.A.KeRneL @  27.1.2007,  09:14 Найти цитируемый пост)
так что можно обойтись, используя только логарифмическое число умножений.»

V.A.KeRneL, добавлю немного кода с пояснением мелочей smile

bas^pot=power(bas,pot)
Код

int power (int bas, int pot) {
//В надежде на то, что компилер соптимирует pot%2 на pot&1 и pot /= 2 на pot>>1.
  int p = 1;
  while (pot > 0) { 
    if (pot%2) { p = p * bas ; }
    bas = bas  * bas ;
    pot / =2;
  }
  return p;
}

Если pot постоянный для нескольких чисел, то можно один раз просто разбить его на биты и вместо pot%2 проверять, имеет бит значение 1, или 0.

Код

int main()
{
int bas[]{123,34,546,678};
int pot=98;
int bitmasklength;
int *potmask=toBitmask(pot,&bitmasklength);

for(int i=0;i<sizeof(bas);i++)
{
printf("%i^%i=%i\n",bas[i],pot,power (bas, potmask,bitmasklength));
}
delete potmask;
}
int power (int bas, int *potmask,int potmasklength) {
  int p = 1;
  for (int i=0;i<potmasklength;i++) { 
    if (pot[i]) { p = p * bas ; }
    bas = bas  * bas ;
  }
  return p;
}

int*potmask(int pot, int*length)
{
int *newmask=new int[32]; //максималъно 32 бита у нас тут
int i=0;
while (pot > 0) { 
    newmask[i]=pot%2
 
    pot / =2;i++;
  }
*length=i;
return newmask;
}



Если необходимо работать по модулю какого-то числа (n), то в цикле надо просто это (%n) вписать после каждого умножения

PS: Код к сожалению проверить не было возможности. Написан "на коленке"
PPS: Вобще-то эти способы (для умножения, степени, проверки на простоту) разработал Лагранж 
Хотя быстрое умножение было известно ещё в древнем Египте.



--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0495 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.