Seb
Seb

Reputation: 11

Outputting pi to n decimal places without rounding (user input)

I am new here, so I apologize for my lack of knowledge.

Pretty much, I am trying to create a program that will allow a user to input a number (n). After the user inputs this number, the program should then output pi to n decimal places, but without rounding the number. For example, if a user inputs "3", I want the output to display 3.141, instead of 3.142.

I managed to write the code to output to n decimal places, but not surprisingly, the output rounds up the number, probably due to the use of the setprecision function. My code can be seen here:

int main()

{
double n;
auto pi = 3.1415926535897932;

cout << "Enter the number of digits of pi you want displayed" << endl;
cin >> n;

cout << std::fixed << setprecision(n) << "Your pi value is:" << pi << endl;
return 0;
}

How do I change this to keep the program from rounding up the number? My only issue with the code is the rounding problem. How do I fix this issue? Thank you in advance.

Upvotes: 0

Views: 551

Answers (1)

Swordfish
Swordfish

Reputation: 13134

On implementations that honour the setting in operator<<*) you can use std::fesetround():

#include <iostream>
#include <iomanip>
#include <cfenv>

int main()
{
    constexpr auto pi{ 3.1415926535897932 };
    std::fesetround(FE_DOWNWARD);

    for(int n = 0; n < 16; ++n)
        std::cout << "Your pi value is: " << std::fixed << std::setprecision(n) << pi << '\n';
}

Output:

Your pi value is: 3
Your pi value is: 3.1
Your pi value is: 3.14
Your pi value is: 3.141
Your pi value is: 3.1415
Your pi value is: 3.14159
Your pi value is: 3.141592
Your pi value is: 3.1415926
Your pi value is: 3.14159265
Your pi value is: 3.141592653
Your pi value is: 3.1415926535
Your pi value is: 3.14159265358
Your pi value is: 3.141592653589
Your pi value is: 3.1415926535897
Your pi value is: 3.14159265358979
Your pi value is: 3.141592653589793

*) Microsofts standard library implementation does not.


Another simple solution would be to use a std::stringstream and print the digits required:

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

int main()
{
    constexpr auto pi{ 3.1415926535897932 };
    std::stringstream ss;
    ss << std::fixed << std::setprecision(16u) << pi;

    for (int n = 1; n < 18; ++n) {
        if (n != 2) // no point in printing "3" and "3." additionally.
            std::cout << "Your pi value is: " << ss.str().substr(0, n) << '\n';
    }
}

With user input:

#include <cstdlib>
#include <limits>
#include <iostream>
#include <iomanip>
#include <sstream>

int main()
{
    constexpr auto pi{ 3.1415926535897932 };
    std::stringstream ss;
    ss << std::fixed << std::setprecision(16) << pi;

    unsigned digits;
    while (std::cout << "How many digits of pi do you want? (up to 16) ",
           !(std::cin >> digits) || digits > 16)
    {
        std::cerr << "Input Error :(\n\n";
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }

    std::cout << "Your pi value is: " << ss.str().substr(0, 2 + digits) << '\n';
}

Upvotes: 2

Related Questions