0

I am trying to print multiple floats, but only some of them need to be a specific decimal place. The user will input two float values, a width and a height. Then the program will calculate the perimeter and area with the two values. Then it will print the values plugged into the equations and show the answer with only one decimal place.

So, an example would look like this:

Width: 3.14
Height: 4.2
Area: 3.14 * 4.2 = 13.2
Perimeter: 2 * (3.14 + 4.2) = 14.7

The issue I am having is that when I go to print the output, I can't get it to print the exact values of the floats that the user inputs and have it print out the answers with only one decimal place. I've tried using setprecision as well as printf, but I just can't get it to work. I tried following answered questions about showing exact decimal places, but nothing has been meeting what I need to do. Here's my code (Sorry if it's sloppy):

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    float width = 0;
    float height = 0;

    cout << "Rectangle Calculator" << endl;
    cout << "Please enter the width: ";
    cin >> width;

    cout << "Please enter the height: ";
    cin >> height;

    float area = width * height;
    float perimeter = 2 * (width + height);

    cout << "Area: " << width << " * " << height << " = " << fixed << setprecision(1) << area << endl;
    cout << "Perimeter: 2 * (" << width << " + " << height << ")" << " = " << fixed << setprecision(1) << perimeter;

return 0;
}

1 Answers1

0

if I understand you correctly you want to print out with the precision that the user used for the input. you can achieve this by first saving the input in a std::string and count the precision from there. Using the greatest precision from the 2 inputs.

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>

bool is_valid_float(std::string str) {
    std::istringstream iss(str);
    float test;
    iss >> std::noskipws >> test;
    return iss.eof() && !iss.fail();
}


unsigned get_precision(std::string input) {
    for (unsigned i = 0u; i < input.length(); ++i) {
        if (input[i] == '.') {
            return (input.length() - i - 1);
        }
    }
    return 0u;
}

int main() {
    float width = 0;
    float height = 0;

    std::cout << "Rectangle Calculator\n\n";


    std::string input;
    do {
        std::cout << "Please enter the width: ";
        std::cin >> input;
        if (!is_valid_float(input)) {
            std::cout << "invalid input\n";
        }
        else {
            break;
        }

    } while (true);

    unsigned max_precision = get_precision(input);
    width = std::atof(input.c_str());

    do {
        std::cout << "Please enter the height: ";
        std::cin >> input;
        if (!is_valid_float(input)) {
            std::cout << "invalid input\n";
        }
        else {
            break;
        }

    } while (true);

    max_precision = std::max(max_precision, get_precision(input));
    height = std::atof(input.c_str());

    float area = width * height;
    float perimeter = 2 * (width + height);

    std::cout << "\nArea: " << width << " * " << height << " = " << std::fixed << std::setprecision(max_precision) << area << '\n';
    std::cout << "Perimeter: 2 * (" << width << " + " << height << ")" << " = " << std::fixed << std::setprecision(max_precision) << perimeter << '\n';

}

example run:

Rectangle Calculator

Please enter the width: 3.4
Please enter the height: 1.5

Area: 3.4 * 1.5 = 5.1
Perimeter: 2 * (3.4 + 1.5) = 9.8
Rectangle Calculator

Please enter the width: 15.125
Please enter the height: 22.0875

Area: 15.125 * 22.0875 = 334.0734
Perimeter: 2 * (15.1250 + 22.0875) = 74.4250

note that float has only about 7.225 correct decimal places:

Rectangle Calculator

Please enter the width: 2.1111111111111
Please enter the height: 3.9999999999999

Area: 2.11111 * 4 = 8.4444446563721
Perimeter: 2 * (2.1111111640930 + 4.0000000000000) = 12.2222223281860

so you should use double instead of float in your program. it achieves 15.955 correct decimal places.

Stack Danny
  • 7,754
  • 2
  • 26
  • 55