функция — Сокращение цифр двойного в переполнении стека

Мне нужна функция, которая снижает точность (количество цифр) моих двойников.

Мне это нужно для расчета, а не для вывода на экран.

То, что я до сих пор, это:

double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
_number *= tenth;
_number = floor(_number);
_number /= tenth;

return _number;
}

призвание setDigits(sqrt(2),3) дает 1.4139999999999999, а не 1.414, как я хочу.

Что я могу сделать?

3

Решение

Что я могу сделать?

К сожалению, ничего для основной проблемы: в вашей платформе 1.414 не имеет точного двойного представления. Вы не можете выполнить вычисление с «1,414», потому что вы не можете разместить «1,414» в любом месте ваш double,

Смотри например http://www3.ntu.edu.sg/home/ehchua/programming/java/DataRepresentation.html .

Что ты Можно сделать, чтобы сохранить ваш номер с максимальной точностью, и дисплей это с пониженной точностью. Вам необходимо рассчитать точность станка и отслеживать ошибки во время вычислений.

Таким образом, вы будете использовать 1.413999999999997 и в конце получите ответ, скажем, 41.99999137; с которым вы будете отображать

printf("The answer is %.3f\n", theAnswer);

Или вы можете изменить платформу (компилятор, или математическую библиотеку, или представление с плавающей запятой, например, использовать long double где поддерживается), но помните, что тогда вы можете получить 1.414 прямо по цене, скажем, 1.873 неправильно (пусть это будет 1.87299999999 или 1.87300000001), и в вычислениях будут примерно такие же ошибки.

Вы можете работать в целочисленной арифметике, умножая начальные числа на 1 000 000 (и получая 1414 000) или другую подходящую шкалу, а затем деля в конце. Целые числа имеют максимальный предел, хотя.

Существуют также библиотеки произвольной точности, которые используют другое внутреннее представление и позволяют вам указывать точность так, как вы хотите, например, GMP ( http://gmplib.org/ ). Конечно, работать с этим сложнее, чем указывать

op1 = 6.0;
op2 = 7.0;
theAnswer = op1 * op2;

и обработка также идет медленнее, но результаты хороши — или так хороши, как вы говорите им.

4

Другие решения

Следующие строки недействительны.

double tenth = pow((double)10,_decimals); //_decimals is not declared
_number = floor(_digits); //should be floor(_number)

Исправленная функция

double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
_number *= tenth;
_number = floor(_number);
_number /= tenth;

return _number;
}

Вот демо.

3

double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
int result = (_number * tenth) + 0.5;
double aux = result / tenth;

return aux;
}

Попробуй это. Для вашего примера за десятый = 1000;

result = 1413,9999999999999 * 1000 +0,5
result = 1414,4......
result = 1414
0

я не знаю, вы не можете проверить этот ответ, но другие делают
Я новичок в C ++, но я нашел способ сделать это

double Point::norm()

{

return (double)floor((sqrt(pow(px,2)+pow(py,2)+pow(pz,2))*1000))*0.001;

}

Я использую это, но вы можете написать свой собственный класс математики, чтобы сделать это для вас

0

Попробуй это:

double setDigits(double _number, int _digits)
{
double tenth = pow((double)10,_digits);
return floor(_number * tenth + 0.5)/tenth;
}

std::cout<<setDigits(sqrt(2),3);

Output: 1.414

-1

Вы можете создать промежуточный класс, который управляет данными внутри int, но входы и выходы как double:

class TruncatedDouble
{
private:
int value_;

public:
TruncatedDouble(double d) : value_((int)(double * 1000)) {}
void SetValue(double d) {value_ = (int)(double * 1000);}
double GetValue() {return (double)value_ / 1000;}
};

Вы также должны перегружать все обычные операторы, но это легко. Пример:

TruncatedDouble& operator+=(const TruncatedDouble& rh) {value_ += rh.value_;}

И так далее. Этот класс будет довольно быстрым, так как вы работаете с int вместо doubleи вы никогда не потеряете точность.

-1
По вопросам рекламы [email protected]