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

Ваш аккаунт

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

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

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

математические функции при работе с длинными числами

41K
13 декабря 2008 года
vakmus
11 / / 25.10.2008
Помогите, пожалуйста!

Пусть у нас есть некоторый класс, скажем, longint, который реализует целочисленную арифметику любой точности в некоторой системе счисления ( пусть, например, будет степенью двойки :). Пусть у нас есть класс fraction вида { longint numerator, denominator; }; реализующий арифметику обыкновенных дробей.
Проблема: реализуя, например, функцию вычисления корня квадратного из 9 методом Ньютона получаю, если в десятичную систему перевести что-то вроде
271050543121376108501863200217485427856445313 /
90350181040458702833954400072495142618815104
при определенной оценке погрешности.

Вопрос: как хорошо можно округлять или что-нибудь делать чтоб три получать?
590
14 декабря 2008 года
Gigahard
223 / / 03.04.2006
Может чем поможет ссылка: http://comp-science.narod.ru/DL-AR/da.html
41K
15 декабря 2008 года
azatik81
1 / / 02.08.2008
А по другому нельзя организовать структуру для хранения длинных чисел? Возможно имеются решения при другой организации данных.
341
15 декабря 2008 года
Der Meister
874 / / 21.12.2007
Цитата:
Вопрос: как хорошо можно округлять или что-нибудь делать чтоб три получать?

Наверное, нужно помыслить над соотношением [(делитель - остаток) / делитель] и прикрутить его к вашей оценке погрешности...

41K
02 мая 2009 года
vakmus
11 / / 25.10.2008
Задача решена.
Я долгое время просто не обращался к ней. Сделано было так. С учетом того, что корень из рационального числа будет числом рациональным в том случае, если и числитель, и знаменатель числа исходного являются полными квадратами, мы делаем так:
Считаем "потолок" корня из числителя. Считаем "потолок" корня из заменателя. Весь этот счет ведем с учетом того, что некоторый временный результат может быть искомым корнем. Если число иррациональное, применяем метод Ньютона.
Код:
//-----------------------------------------------------------------------------------
    template<class C> longint temp_sqrt( const C &num )
    {
        // Вычисляем потолок для корня из num
        int i = 0;  // № cтепени двойки, превышающей искомый корень
        longint x( static_cast<uint32>(1) );    // cтепень двойки, превышающая искомый корень
        for( ; sqr( x ) < num; x <<= 1, i++ );
        // Делением попалам отрезка между последовательными степенями двойки уточняем
        //      первое приближение сверху с точностью до 1
        if( i > 1 )
        {          
            longint subst = x >> 2; // вычитаемое
            longint middle; // середина текущего отрезка
            longint temp;
            for( ; i != 1 ; i-- )   // до тех пор, пока расстояние (вычитаемое == 0) не будет равно 1
            {
                middle = x - subst;
                temp = sqr( middle );
                if( temp > num ) x = middle;
                else
                    if( temp == num ) return middle;
                subst >>= 1;
            }
        }
        return x;
    }
   
//-----------------------------------------------------------------------------------
    fraction sqrt( const fraction &f )
    {
        // Вычисление квадратного корня
        if( f < static_cast<uint32>(0) ) throw range_check_error("sqrt");
        // Вдруг корень рациональный ?
        const fraction temp( temp_sqrt( f.numerator()), temp_sqrt( f.denominator()) );
        if( sqr( temp ) == f ) return temp;
        // Если корень иррациональный уточняем первое приближение x_(n+1)-ое до потолка искомого корня
        fraction x_n1( temp_sqrt( f ) );
        fraction x_n ( 0 ); // x n-ое    
        while( abs( x_n1 - x_n ) >= eps )   // метод Ньютона для функции x**2 - f
        {
            x_n  = x_n1;
            x_n1 = ( x_n + f / x_n ) / static_cast<uint32>(2);
        }
        return x_n1;
    }


В качестве примера можно отметить, что корень из 2000, без применения предварительной подготовки и с оценкой погрешности 1/100000000000000000000, выдавал число, имеющее в числителе и в знаменателе порядка 150 разрядов в системе счисления 2**32, с подготовкой знаков стало 5.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог