IPB
ЛогинПароль:

> Деление с высокой точностью
сообщение
Сообщение #1


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Всем привет! Необходимо получить результат деления двух предположительно целых чисел не превышающих 100 с точностью до 1000 знаков после разделителя, пытаюсь нагуглить какие-либо алгоритмы, пока безуспешно. На форуме поиск деление+точность результатов тоже не дал sad.gif Буду рад любым подсказкам. !4.gif

добавлено: собственно деление столбиком никто не отменял)) туплю под вечер)

Сообщение отредактировано: klem4 -


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Да, скорость в данном случае мне не важна, намалевал на скорую руку(крайне не оптимизировано и не красиво), но может кому пригодится, работает без учета округления (так нужно было для решаемой мной задачи), то есть
1 / 200 = 0.005, с точностью до двух знаков результат работы функции = '0.00'.


// точность дробной части числа заданного в стороке s
int get_accuracy( std::string s )
{
    size_t dot_pos = s.find(".");

    if ( dot_pos == std::string::npos )
	return 0;

    return s.size() - (int)dot_pos - 1;
}

std::string complete( std::string s, int accuracy, int cur_accur )
{
    if ( cur_accur == accuracy )
	return s;

    if ( cur_accur == 0 )
    {
	s += ".";
    }

    while ( cur_accur < accuracy )
    {
	s += "0";
	++cur_accur;
    }

    while ( cur_accur > accuracy )
    {
	s.erase(s.length() - 1, 1);
	--cur_accur;
    }

    if ( s[s.length() - 1] == '.' )
    {
	s.erase(s.length() - 1, 1);
    }

    return s;
}

std::string divide(int n, int m, std::string result, int accuracy, int iteration )
{
    //std::cout << "CALL " << n << "/" << m << std::endl;
    
    int cur_accur = get_accuracy(result);
    if ( (iteration > 1000 ) || (n == 0) || ( (accuracy > 0) && (accuracy <= cur_accur) ) )
    {
	// some actions
	return complete(result, accuracy, cur_accur );
    }

    int add_zero = 0;
    while ( n < m )
    {
	n *= 10;
	//	if ( n < m )
	    ++add_zero;
    }

    //std::cout << "add_zero = " << add_zero << std::endl;

    if ( add_zero > 0 )
    {
	// у числа нету дробной части
	if ( cur_accur == 0 )
	{
	    // у числа нету Целой части
	    if ( result.length() == 0 )
	    {
		result = "0.";
		--add_zero;
	    }
	    else
	    {
		result += ".";
		--add_zero;
	    }
	}
	else
	{
	    --add_zero;
	}

	while ( add_zero-- > 0 )
	{
	    result += "0";
	}
    }

    int int_part = n / m;
    int T = int_part;
    std::string str_part = "";

    while ( T > 0 )
    {
	str_part = (char)((int)'0' + T % 10) + str_part;
	T /= 10;
    }

    //std::cout << "STR_PART = " << str_part << std::endl;

    result += str_part;
    n -= int_part * m;

    return divide(n, m, result, accuracy, iteration + 1 );
    //return result;
}



вызов

int n, m, k;
    std::cin >> n >> m >> k;
    std::cout << divide(n, m, "", k, 0) << std::endl; // n / m с точностью k знаков после разделителя



--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 14.03.2025 15:02
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name