What is the best data type to use for money in C#?
As it is described at decimal as:
The decimal keyword indicates a 128-bit data type. Compared to
floating-point types, the decimal type has more precision and a
smaller range, which makes it appropriate for financial and monetary
calculations.
You can use a decimal as follows:
decimal myMoney = 300.5m;
What is the correct way of storing the result of a float expression into an int variable in C?
159.95 does not have a precise representation
That is correct (as your printf
call shows). However, the dollars * 100
operation, which is performed in at least float
precision1, yields a value of exactly 15595.0000, as the following code demonstrates:
#include <stdio.h>
int main()
{
float dollars = 159.95f;
float p = dollars * 100;
if (p == 15995.00000) printf("Exact!\n");
else printf("Not exact: truncation may occur!\n");
return 0;
}
That this happens here is purely "by chance". If you change that 159.95 to (say) 159.65, then you will see your expected truncation in the value of cents
(15964).
You can experiment some more, here: with a value of 159.85, for example, the best representation for the calculated value of dollars * 100
is slightly larger than the exact value (15985.000977), so the truncation also won't happen in that case.
1 The 100
, which is an int
literal is converted to a float
before the multiplication operation is performed.
C++ Money Class - storing and rounding cents
#include <cmath>
CENTS = round(tmpCent);
Due to floating point representation, this may not always give the right result. The closest you can get is have a margin of error epsilon, say
#define EPS 0.000001
then you can do
CENTS = round(tmpCent + EPS);
Note that this will accept values that are represented as 0.499999 <= x < 0.5
And it's preferable to use double
and not float
to keep the precision as close as possible.
What is the best way to store a money value in the database?
Decimal and money ought to be pretty reliable. What i can assure you (from painful personal experience from inherited applications) is DO NOT use float!
Best way to store ROE in C#
Typically I use a variation of the following class.
public ForexSpotContainer : IEnumerable<FxSpot>
{
[DataMember] private readonly Dictionary<string, FxSpot> _fxSpots;
public FxSpot this[string baseCurrency, string quoteCurrency]
{
get
{
var baseCurrencySpot = _fxSpots[baseCurrency];
var quoteCurrencySpot = _fxSpots[quoteCurrency];
return baseCurrencySpot.Invert()*quoteCurrencySpot;
}
}
public IEnumerator<FxSpot> GetEnumerator()
{
return _fxSpots.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
I tend to then create a Money
class and a FxSpot
class then create +-*/ operators for the Money and FxSpot classes so that I can do financial calculations in a safe way.
EDIT: I my experience, when working in financial systems, I have always had issues with code like this
decimal sharePriceOfMsft = 40.30m;
decimal usdEur = 0.75m;
decimal msftInEur = sharePriceOfMsft * usdEur;
Since it always takes a few second for me to check if I should multiply the spot or divide.
The problem is compounded when I have to use Forex Crosses, such as JPYEUR or EURJPY etc, and hours were lost to subtitle bugs from close Forex Spots.
Also of consequence is the dimensional analysis of equations. When you multiple lots of numbers together and you expect a Price, are you sure you didn't mess up a multiple/divide. By creating a new class for each unit, you have a little more compile time error checking that can ultimately save you seconds for each line of code you read (which in a many thousand line library will add up to hours very quickly).
Type for large currency values in C++
Thanks you all for your answers. I found the most appropriate solution myself. It's just one file that does everything i need - C++ wrapper class for the OLE Automation type DECIMAL. It's really light (no additional heavy libraries or files) and powerfull and can handle REALLY BIG numbers.
Related Topics
How to Assert That a Constexpr If Else Clause Never Happen
Cout Not Printing Unsigned Char
Why Should the System() Function Be Avoided in C and C++
Define Bitset Size At Initialization
Opengl - Index Buffers Difficulties
Why Is This Program Erroneously Rejected by Three C++ Compilers
Best C++ Ide or Editor For Windows
Why Does the C++ Stl Not Provide Any "Tree" Containers
How to Compile For Windows on Linux With Gcc/G++
The New Syntax "= Default" in C++11
Virtual Functions and Performance - C++
How to Call Erase With a Reverse Iterator
Do I Need to Manually Close an Ifstream
Generate Random Numbers Following a Normal Distribution in C/C++
Enforcing Statement Order in C++
Virtual Assignment Operator C++
When Were the 'And' and 'Or' Alternative Tokens Introduced in C++