Огромные числа в Pascal

Общие вопросы: версии и диалекты, синтаксис языка, cтруктуры и типы данных (массивы, строки, списки...), обработка данных и т.д.
Ответить
Dim...ON
Сообщения: 75
Зарегистрирован: 28 янв 2008, 01:10
Контактная информация:

Подскажите добры молодцы, кто знает.... в каком виде лучше юзать огромные числа в Паскале? огромные это порядка x=10^40, так чтобы при этом вычитание единицы из этого числа, а потом деление на него же не давало в ответе единицу... ну т.е., чтобы машинная погрешность не влияла на такие вычисления
в моём случае исходное число - целое, но целочисленные типы не подходят, т.к. самый большой Longint ограничен двумя с хвостом миллиардами... я пробовал Extended, но почему-то операция (x-1)/x даёт в ответе 1
не подскажете кто чем богат? буду благодарен
Аватара пользователя
Duncon
Сообщения: 2085
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

Бери с плавающей точкой числа если не влазаешь в целые - там степени шкалят(очень большие есть) далее либо округляй результаты либо отсекай дробную часть..
[syntax=Delphi] [/syntax]
Dim...ON
Сообщения: 75
Зарегистрирован: 28 янв 2008, 01:10
Контактная информация:

так я ж говорю, я итак беру Extended.... числа там большие, самые большие в Паскале, но хранит он их кажется в формате с плавающей точкой... например:
3.42545698371658E+0038
а в описании типа Extended сказано, что точность у него до 19 порядка, т.е. я так понимаю что число сорокового порядка он получил, а как только запомнил, всё что после 19-го порядка отсеклось... и соответственно вычитание единицы из сорокового порядка уже невозможно... вот что за проблема
округлить число сорокового порядка тоже не представляется возможным, т.к. Round имеет тип Longint, а он вообще на 9 порядке заканчивается
может быть у меня какое-то неправильное видение и возможно таки заставить его видеть разряды сорокового порядка? не зря же Extended сделали четырёхтысячного порядка, иначе он на фиг был бы не нужен
Аватара пользователя
Duncon
Сообщения: 2085
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

Это вопросы округления, найди альтернативные варианты..
[syntax=Delphi] [/syntax]
Dim...ON
Сообщения: 75
Зарегистрирован: 28 янв 2008, 01:10
Контактная информация:

Не подскажешь какой-нибудь? Мои мысли иссякли
И поможет ли это? Не потерялись ли уже разряды, начиная с 20-го после того как число уже присвоено переменной типа Extended?
Я подумывал над тем, чтобы написать модуль работы с большими числами через строки, но овчинка не стоит выделки, да и там возникает тот же вопрос с потерей последних разрядов после запоминания числа
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Дело в том, что хоть и Extended позволяет хранить числа порядка 10^300, но разброс хранимых чисел неоднороден в каждом порядке. И разница двух "соседних" очень больших чисел может достигать и 10^4 и 10^6.
Придумай свой формат. Или юзай очень старый медот хранения псевдо-дейсвтвительных чисел - в котором дробная часть хранится отдельно от целой. Например FLOAT16:16 означает что в 32 битном числе первые 16 бит принадлежат целой части, остальные 16 - дробной. С такими числами удобно работать используя обычные целочисленные команды деления и умножения, обрабатывая целую и дробную часть по отдельности и комбинируя результаты. Кроме того все числа во всем диапазоне распределены однородно и точность не будет зависеть от величины самого числа. В твоем случае можно за довольно небольшое время написать модуль для работы с числами формата FLOAT32:32, но поскольку порядок твоих чисел 40, то должен подойти формат FLOAT128:32 или FLOAT160:32.
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
Еще дам небольшую подсказку. Основная математика деления и умножения таких чисел кроется в их формате. Числа представляют в виде (Ai + Af/(2^N)) - где Ai - целая часть, Af - дробная часть, N - количество разрядов дробной части. Тогда умножение будет выглядеть как (Ai + Af/(2^N))*(Bi + Bf/(2^N)) = (Ai + Af/T)*(Bi + Bf/T) = Ai*Bi + Bi*Af/T + Bf*Af/T + Af*Bf/(T^2) = Ai*Bi + (Bi+Bf)*Af/T + Af*Bf/(T^2).
Далее приводим все к знаменателю T^2, числитель сдвигаем на 2N бит (т.к. Т^2=2^(N^2)) получив тем самым целую часть, а старшие N бит из младших 2N бит :) полагаем за дробную часть. С делением немного по другому, но принцип тот же. Сложение и вычитание элементарны и описывать их не стоит. Стоит обратить внимание, что при создании этого модуля полезно ввести отдельную процедуры для умножения и сложения чисел типа INT128 или INT160, кажется кроме этих операций здесь более ничего нужно не будет.
It's a long way to the top if you wanna rock'n'roll
Хыиуду
Сообщения: 2442
Зарегистрирован: 06 мар 2005, 21:03
Откуда: Москва
Контактная информация:

Вроде бы был тип данных Comp, который хранится как дробный, но позволяет работать с целыми до 10^64. Не уверен, не проверял.
Искусство программирования - заставить компьютер делать все то, что вам делать лень.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
Ответить