Помощь - Поиск - Пользователи - Календарь
Полная версия: Деление с высокой точностью
Форум «Всё о Паскале» > Разработка ПО, алгоритмы, общие вопросы > Алгоритмы
klem4
Всем привет! Необходимо получить результат деления двух предположительно целых чисел не превышающих 100 с точностью до 1000 знаков после разделителя, пытаюсь нагуглить какие-либо алгоритмы, пока безуспешно. На форуме поиск деление+точность результатов тоже не дал sad.gif Буду рад любым подсказкам. !4.gif

добавлено: собственно деление столбиком никто не отменял)) туплю под вечер)
Lapp
Цитата(klem4 @ 11.04.2011 22:36) *
добавлено: собственно деление столбиком никто не отменял)) туплю под вечер)
хихи)) разве это вечер? smile.gif я туплю обычно по утрам ))

На этот раз скорость не играет большой роли?
Где-то у меня была арифметика для чисел любой длины в любой СС, причем как целая так и дробная. Надо пошукать - мож, для FAQ сгодится..
klem4
Да, скорость в данном случае мне не важна, намалевал на скорую руку(крайне не оптимизировано и не красиво), но может кому пригодится, работает без учета округления (так нужно было для решаемой мной задачи), то есть
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 знаков после разделителя

Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.