Как ограничить кол-во символов после точки при вводе данных в С++?

Как это делать при выводе я в курсе, используя: std::fixed << std::setprecision(x)
В отладчике возникает ситуация, что в конце он дописывает 1 и у меня при выводе таблицы пропадает 20 шаг и результат Х из-за этого. Каким образом можно ограничить кол-во символов при присвоении переменной значения?

65b273a0d372d143828924.png
65b273a78ff71145635242.png

#include <iostream>
#include <cmath>
#include <iomanip>
#include <string>

double calculateExpression(double x) {
    double result = 0;
    result = log(abs(95 / 10) + 4) * (1 - 95 / cos(x - 95)) * (sin(x) / 95);
    if (cos(x - 95) == 0 && sin(x) / 95 == 0 && log(abs(95 / 10) + 4) * (1 - 95 / cos(x - 95)) * (sin(x) / 95) < 0) {
        std::string str = std::to_string(result);
        std::cout << "Error" << result << std::endl;
    }
    return result;
}

void printTable(double startX, double endX, double step) {
    std::cout << std::right << std::string(10, ' ') << std::string(60, '-') << std::endl;
    std::cout << std::right << std::setw(10) << "|" << " N " << std::right << std::setw(9) << " | " << std::right << std::setw(10) << std::right << std::setw(10)
        << " X " << std::right << std::setw(10) << " | " << std::right << std::setw(20) << " Expression " << std::right << std::setw(10) << " | " << std::endl;
    std::cout << std::right << std::string(10, ' ') << std::string(60, '-') << std::endl;
    int rowNum = 1;
    double x = startX;
    while (x <= endX) {
        double expressionValue = calculateExpression(x);
        std::cout << std::right << std::setw(10) << "|" << std::right << std::setw(3) << rowNum << std::right << std::setw(8) << "|" << std::right << std::setw(10) 
            << std::setprecision(7) << x << std::right << std::setw(10) << "|" << std::right << std::setw(10) << std::fixed << std::setprecision(6) << expressionValue
            << std::right << std::setw(20) << "|" << std::endl;
        rowNum++;
        if (step > 0) {
            x += step;
        }
        else {
            x -= step;
        }
        std::cout << std::right << std::string(10, ' ') << std::string(60, '-') << std::endl;
    }
}

int main() {
    double startX = 0, endX = 0, step = 0;
    std::cout << "Initial value for X: ";
    std::cin >> startX;
    std::cout << "Final value for X: ";
    std::cin >> endX;
    do {
        std::cout << "Variable change step deltaX: ";
        std::cin >> step;
    } while (step == 0);
    printTable(startX, endX, step);
    return 0;
}
  • Вопрос задан
  • 107 просмотров
Пригласить эксперта
Ответы на вопрос 2
@res2001
Developer, ex-admin
Никто ничего не дописывает. Дело в специфике хранения данных в числах с плавающей точкой.
Эти числа всегда приближенные. Грубо говоря даже какое-то целое число, типа 3, будет храниться как: 2.9999999999999999999.
Конкретно 3 будет иметь точное представление, но другие числа будут иметь приближенное представление. Поэтому работая с числами с плавающей точкой лучше всегда иметь ввиду, что это число приближенное.
Можете почитать что-нибудь по стандарту IEEE754 - стандарт чисел с плавающей точкой, который сейчас используется повсеместно. Так же в интернете есть сайты, где можно глазами увидеть как представляется то или иное число с плавающей точкой в компьютере. Например можете тут посмотреть: https://www.h-schmidt.net/FloatConverter/IEEE754.html
Ответ написан
Комментировать
AshBlade
@AshBlade
Просто хочу быть счастливым
Если нужно округление до определенного кол-ва знаков после запятой, то вот это может помочь:
unsigned int powers[] = {1, 10, 100, 1000, 10000, 100000};

double round_precision(double number, unsigned int precision) {
  unsigned int coef = powers[precision];
  long temp = number < 0 ? -number * coef : number * coef;
  return (double)temp / coef;
}


Также есть вариант записывать число в std::stringstream с нужной точностью, а потом десериализовывать, но т.к. это затратно для этого случая не описал.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы