Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Остаток от деления 
:(
    Опции темы
poisonX
Дата 18.2.2006, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Помогите решить вопрос: необходимо найти остаток от деления очень большого числа на другое не обязательно большое.

Например:

e := 1,00175779247994E3664;
n := 3239;

Необходимо найти: ost := e mod n;

Дело в том, что в памяти e помещается только как тип extended (хотя нет необходимости чтобы оно являлось с плавающей точкой), но операцию mod можно проводить только с целыми числами, а в любое из integer такое число переполняет. Как быть в этом случае?
PM MAIL   Вверх
Fin
Дата 18.2.2006, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дракон->Спать();
**


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

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



У тебя настолько будет большая целая часть, что я не думаю, что у тебя класическими методами получится выташить остаток от деления. Надо использовать библиотеки поддерживаюшие большие числа.


--------------------
Пролетал мимо.
PM MAIL   Вверх
poisonX
Дата 18.2.2006, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Как это сделать?
PM MAIL   Вверх
Fin
Дата 18.2.2006, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дракон->Спать();
**


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

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



Иши библиотеку арифметики большого числа. Или создай ее сам. Просто у тебя число настолько большое, что будет откидываться часть числа при делении. И естественно это будет сказываться на конечном результате.


--------------------
Пролетал мимо.
PM MAIL   Вверх
poisonX
Дата 18.2.2006, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Да скорее всего никакого результата не будет, т.к при обработки такого числа происходит исключение.
PM MAIL   Вверх
Guedda
Дата 18.2.2006, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

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



А почитать документацию по модулю Math.pas?
Там очень много всего есть smile


--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
poisonX
Дата 18.2.2006, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Например?
PM MAIL   Вверх
Fin
Дата 18.2.2006, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дракон->Спать();
**


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

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



Можно сделать так. Последовательно выбирать целую часть из числа.
1. Все что после Е откладываем пока в сторонку. У нас останется только 1,00175779247994
2. Доводим это число, так чтобы оно было больше 3239 При этом отнимаем разрядность у числа E
10017,5779247994
Е=3664-4=3660
При каждом декременте Е нужно все время проверять, чтобы Е была больше нуля. Как только Е стало равно 0, перейти к шагу 6.
3. Ишем Число которое было бы кратно числу 3239, но приэтом максимально было бы приближено к делимому 3239*3 = 9717
4. Отнимаем от 10017,5779247994 - 9717 = 300,5779247994
5. Переходим к шагу 2 только Теперь для числа полученного в шаге 4
6. конец


--------------------
Пролетал мимо.
PM MAIL   Вверх
Fin
Дата 18.2.2006, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дракон->Спать();
**


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

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



Я накидал програмку по этому алгоритму на С++. У меня получился ответ 2516. Чуть помудрив с алгоритмом, и перевёл все в целочисленное исчисление получился ответ 1003.

Это сообщение отредактировал(а) Fin - 18.2.2006, 13:25


--------------------
Пролетал мимо.
PM MAIL   Вверх
Guedda
Дата 18.2.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

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



Можешь выложить Сишный код сюда, я посмотрю ??


--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
Fin
Дата 18.2.2006, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дракон->Спать();
**


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

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



Код

#include <iostream.h>
#include <windows.h>
int main()
{
    DWORD x = 3176;   // 100175779247994 % 3239
    DWORD y = 3239;
    int e=3650;
    while (true)
    {
        while (x<y)
        {
            x *=10;
            e--;
            if (e==0) 
            {
                if (x>y) while (x>y) x -=y;
                cout << x;
                return 0;
            }
        }
        while (x>y) x -=y;

    }


    return 0;
}

Добавлено @ 13:48
Тут остались следы от не целочисленного вычисления smile Не хотел делить лишний раз, чтобы не делать еше больше ошибок при вычислении.
Добавлено @ 13:54
Вот Код почишенный
Код

#include <iostream.h>
int main()
{
    int x =    3176;
    int y = 3239;
    int e=3650;
    while (true)
    {
        while (x<y)
        {
            x *=10;
            e--;
            if (e==0) 
            {
                x %=y;
                cout << x;
                return 0;
            }
        }
        x %=y;

    }


    return 0;
}



--------------------
Пролетал мимо.
PM MAIL   Вверх
Albinos_x
Дата 18.2.2006, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

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



простенький вариант:
Код
...
uses
  ... , math;
...
// с условием, что значение E+3664; всегда целочисленное 
procedure TForm1.Button1Click(Sender: TObject);
var e:Extended;
    n:Extended;
    ll:integer;
    s,ss:string;
begin
e := 1.00175779247994E+3664;
n := 3239;
s:=floattostr(e);
ss:=floattostr(n);
if pos('E',s)>0 then
   begin
   if pos('E',ss)>0 then
      begin
      ss:=copy(s,pos('E',ss)+1,length(ss));
      ll:=strtoint(ss);
      end
      else
      ll:=length(ss);
    s:=copy(s,pos('E',s)+1,length(s));
    ll:=ll+trunc((strtofloat(s)/(ll-1)-trunc(strtofloat(s)/(ll-1)))*ll);
    ll:=strtoint(s)-ll;
    e:=e*(power(10,-ll));
    end;
while e>n do
   e:=e-n;
Edit1.Text:=floattostr(e);


результат := 3005,779247994



--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
poisonX
Дата 18.2.2006, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Так, вроде ответ-то должен быть равен 189
PM MAIL   Вверх
Mayk
Дата 18.2.2006, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

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



1) google говорит, что сущетвуют ExtMod, ExtRem ф-ции в какой-то ESBMaths'е. хмм.
2) В теории может работать вот это
(мы вычитаем делитель из делимого пока можем. Для скорости мы вычитаем не один делитель, а 2**i*делитель, где i мы вначале увеличиваем, а потом уменьшаем )

Код

function fmod(a,b : extended) : extended;
var i : integer;
begin
        i := 1;
        while (a >= b) do begin
                a := a - b;
                b := b * 2;
                i := i + 1;
        end;

        while (i > 1) do begin
                b := b / 2;
                while (a >= b) do 
                        a := a - b;
                i := i - 1;
        end;
        
        fmod := a;
end;

Но на практике - резултат для примера 2838.00.
А вот java'вский big decimal говорит, что результат - 1003.
Нда.


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Albinos_x
Дата 18.2.2006, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

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



виндовский калькулятор говорит
Цитата

2352



--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


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

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


 




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


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

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