Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Помогите исправить ошибку Overflow

82K
25 мая 2012 года
Ruslan05
4 / / 25.05.2012
Private Sub Command1_Click()

Dim a As Double
Dim c As Double
Dim b As Double


a = Text1.Text
c = 2 ^ a
b = c Mod 989
Text2.Text = c
Text3.Text = b

End Sub

Выдает ошибку overflow !

Задача типа 2^(154) mod 989 = 1
Где 'а' Степень (154) подставляется в диапазоне от 1 до 6112
Как написать программу для такой задачки ?
72K
25 мая 2012 года
CorsaiR
59 / / 07.03.2012
Какое а вводишь?
2^a, по-ходу, не влазит в диапазон Double.
82K
25 мая 2012 года
Ruslan05
4 / / 25.05.2012
Под 'а' ввожу от 1 до 6012.
А что можешь посоветовать тогда вместо типа данных Double ?
82K
25 мая 2012 года
Ruslan05
4 / / 25.05.2012
Цель всего получить результат типа 2^(154) mod 989 = 1
285
25 мая 2012 года
Romik
479 / / 24.11.2002
Прекрасная цель, но 2^154 - это будет 22835963083295358096932575511191922182123945984 - 47 знаков в десятичной записи (попробуй его вслух прочитать)
Максимум на что можно рассчитывать, это Decimal, у которого MaxValue - 79228162514264337593543950335, т.е. 29 знаков в десятичной записи.

Если вам действительно нужна арифметика больших чисел, используйте для этого сторонние библиотеки.
2.1K
25 мая 2012 года
disputant
95 / / 28.05.2007
Люди, вы что?!!
На фига там длинная математика?!!!

Сказано же - интересует результат - ПО МОДУЛЮ!!!

Я Басик не знаю, так что код набросать не могу, но в простейшем варианте - цикл из 154 (умножение + взятие по модулю)...

Кстати, ответ для 154 - 1, для 6012 - 64...

Попытался вспомнить уроки 30-летней давности, что-то вроде (не знаю, как там у вас по модулю, то бишь остаток... - написал MOD...)

 
Код:
RES = 1
FOR I = 1 TO A
    RES = RES * 2 MOD 989
NEXT I
285
26 мая 2012 года
Romik
479 / / 24.11.2002
ну тогда я не понимаю задачу.
явно указано, 2 ^ (154), откуда тут берётся цикл в 154 итерации?
341
26 мая 2012 года
Der Meister
874 / / 21.12.2007
Цитата: Romik
ну тогда я не понимаю задачу.
явно указано, 2 ^ (154), откуда тут берётся цикл в 154 итерации?

(a * b) mod c = ((a mod c) * (b mod c)) mod c
Кстати, насколько я понимаю, у умножения и операции взятия остатка приоритет одинаков.

 
Код:
RES = 1
FOR I = 1 TO A
    RES = (RES * 2) MOD 989
NEXT I
Тип RES должен быть целочисленным, а не числом с плавающей запятой, как у ТС.
2.1K
26 мая 2012 года
disputant
95 / / 28.05.2007
Цитата: Romik
ну тогда я не понимаю задачу.
явно указано, 2 ^ (154), откуда тут берётся цикл в 154 итерации?



Чтоб переполнения избежать.

2.1K
26 мая 2012 года
disputant
95 / / 28.05.2007
Цитата: Der Meister
Тип RES должен быть целочисленным, а не числом с плавающей запятой, как у ТС.



Само собой, просто, как я уже говорил - Басика не помню совершенно, как там int указать, не знаю.

И - раз приоритет умножения и остатка одинаков, то скобка там как раз и не нужна :) - они же левоассоциативные операции.

445
26 мая 2012 года
Charley
176 / / 16.08.2011
Быстрое возведение в степень: алгоритм на wikipedia
2.1K
26 мая 2012 года
disputant
95 / / 28.05.2007
Цитата: Charley
Быстрое возведение в степень: алгоритм на wikipedia


Да конечно, можно и так, можно (раз это конкретно двойка) и еще проще - десятками и сотнями...
Только для таких микрочисел - до 6000 - смысла не имеет...

285
26 мая 2012 года
Romik
479 / / 24.11.2002
Признаю, выполнять операции в цикле вполне себе эффективно. Но я не понимаю, как вы пришли к подобным выводам. Я отталкивался от утверждения:
Цитата: Ruslan05
Цель всего получить результат типа 2^(154) mod 989 = 1


Ниже было следующий комментарий:

Цитата: Der Meister
(a * b) mod c = ((a mod c) * (b mod c)) mod c


В одном случае возведение в степень, в другом - умножение. Я понимаю, что a возвести в степень n, это значит a умножить n раз на a. Но почему в процессе умножения можно ещё и брать значение по модулю, при этом ответ должен быть верным - не понимаю, так как мне представляется это двумя разными задачами.

2.1K
26 мая 2012 года
disputant
95 / / 28.05.2007
Гм... даже не знаю, как и пояснять :)

Ну если 2^n = 989* m + r, то очевидно, что 2^n mod 989 = r, а 2^(n+1) = 2*989*m+2*r, так что 2^(n+1) mod 989 = (2*r) mod 989...

Так что по индукции, можно считать, корректность алгоритма доказана. Инвариант цикла - после k-й итерации полученное значение представляет собой 2^k mod 989. Начальное - для 0 - очевидно (2^0 есть 1 что по модулю, что без модуля...), индуктивный переход доказан выше.

Более просто - ну, затрудняюсь даже, как пояснить еще проще...
285
26 мая 2012 года
Romik
479 / / 24.11.2002
По крайней мере ясно, что утверждение выше не является результатом невнимательности к условию. С математикой попробую разобраться сам.
82K
27 мая 2012 года
Ruslan05
4 / / 25.05.2012
Спасибо Огромное! Все заработало!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог