Ricky Kresslein
Ricky Kresslein

Reputation: 419

Store float with exactly 2 decimal places in C++

I would like to take a decimal or non-decimal value and store it as a string with exactly 2 decimal places in C++. I want to do this to show it as a monetary value, so it is always $10.50 or $10.00 rather than $10.5 or $10.

I don't just want to print this, I want to store it, so I don't believe setprecision will work here. I'm doing this in a Qt application, so if there is a way to do it using Qt I can use that as well.

For example:

int cents = 1000;
std::string dollars; //should get value from cents formatted to 10.00

UPDATE: It seems I don't have the vocabulary yet as I am just beginning to learn C++ to articulate what I am trying to do. Here is what I want to do using Python:

str_money = '$ {:.2f}'.format(num)

In this example, num can be a decimal or not (10 or 10.5 for example) and str_money is a variable that is assigned the value of num as a decimal with exactly 2 numbers after the decimal (in this example, str_money would become 10.00 or 10.50). I want it to store this in a string variable, and I don't need it to store the '$' with the value.

Can I do this in C++?

Upvotes: 1

Views: 3479

Answers (3)

heap underrun
heap underrun

Reputation: 2489

Your decision to store monetary amounts as integer number of cents is a wise one, because floating-point data types (such as float or double) are generally deemed unsuitable for dealing with money.

Also, you were almost there by finding std::setprecision. However, it needs to be combined with std::fixed to have the expected effect (because std::setprecision means different things depending on which format option is used: the default, scientific or fixed).

Finally, to store the formatting result in an std::string instead of directly printing it to the console, you can use a string-based output stream std::ostringstream. Here is an example:

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

std::string cents_to_dollars_string(const int cents)
{
    static constexpr double cents_per_dollar{ 100. };
    static constexpr int decimal_places{ 2 };

    std::ostringstream oss;
    oss << std::fixed << std::setprecision(decimal_places) << cents / cents_per_dollar;
    return oss.str();
}

int main()
{
    const int balance_in_cents{ -420 };
    const std::string balance_in_dollars{ cents_to_dollars_string(balance_in_cents) };
    std::cout << "Your balance is " << balance_in_dollars << '\n';
}

Here, we first define the function cents_to_dollars_string, which takes the amount in cents as an int and returns an std::string containing the formatted amount of dollars. Then, in main we call this function to convert an amount (in cents) stored in an int variable balance_in_cents to a string and store it into an std::string variable balance_in_dollars. Finally, we print the balance_in_dollars variable to the console.

Upvotes: 4

Kyle A
Kyle A

Reputation: 980

If you want to store a fixed number of decimal places, a float is not what you want. You want a fixed-point number. With money, the basic idea is to store the value as "cents" in an integer. Then you can perform a division by 100 whenever you want to output the value as "dollars". (Or have a custom output function or operator that formats the output correctly.)

One of the big benefits to fixed-point arithmetic is that you can avoid rounding errors. Floating point numbers are really bad at exactly storing decimal fractions, so dealing with "tenths" or "hundredths" can easily result in rounding errors that can add up in long running, or complicated programs.

How you implement your fixed point numbers is largely up to you. You might find a library that has a fixed-point class, you could implement your own, or you could just manipulate integer variables.

Upvotes: 1

Hassan Mansour
Hassan Mansour

Reputation: 11

If you want this happen on output then you can use setprecision () method as it sets the decimal precision to be used to format floating-point values on output operations.

find more https://www.cplusplus.com/reference/iomanip/setprecision/#:~:text=std%3A%3Asetprecision&text=Sets%20the%20decimal%20precision%20to,input%20streams%20or%20output%20streams).

and check this solution for the problem

https://www.geeksforgeeks.org/rounding-floating-point-number-two-decimal-places-c-c/

Upvotes: 0

Related Questions