How to lose a penny all the time?

I will work in a company where they program financial institutions, and I will work a lot with money. Previously, this did not cause me serious concern, because I was making little money, and at one point Double was enough, but now even 1 penny is damn important.

I think everyone can know

Dim mValue as Decimal = 100 'seems the best type for now mValue = mValue / 3 Console.WriteLine(mValue) Console.ReadLine() mValue = mValue * 3 Console.WriteLine(mValue) 'Outputs 99.9999999999999999999999999... and never hits 100 

So, how can I overcome this problem and find even more accurate results?

Thanks.

+6
source share
5 answers

I am not a specialist in this field, so someone with more experience can answer this better.

You can safely move to 10,000 digits or so, and then round to the nearest penny when you want to use the number. This works for the example you posted

100/3 = 33.333333333333333 * 3 = 99.99999999999, which is then rounded to 100.

I know that many things use what is called banker rounding. This is done to prevent the loss of money when something ends exactly 5. It is rounded if the number is 5 odd, and rounded if the number is even. Something to consider.

http://en.wikipedia.org/wiki/Rounding

+2
source

If you need to be able to do arbitrary division, it looks like you need a representation of a rational number (fraction). I don’t believe that .NET provides one by default, and you will have, um, “fun” to implement it in a way that will work just like built-in numeric types. This can make you go for addition, subtraction, multiplication and division, but it will not help if you also need irrational numbers (for example, with square roots).

Are you sure you will divide by 3? Are you sure you cannot round (say) the next thousand pennies? You must find out exactly what requirements you will find in your calculations - I doubt that you really need to be infinitely accurate.

+5
source

When you are dealing with money, you should never share it. You must distribute the amount as evenly as possible, resulting in a list of distributions, for example:

 100 allocated by 3 = [ 33, 33, 34 ] 

Someone should get this extra penny.

In addition, it is easier to use an integer representing the number of pennies than using a decimal number.

And, encapsulate cash transactions - this is a dedicated class. Take a look at Money .

+4
source

Can you offer me an example of real life use for this?

 mValue = mValue / 3 

Divide $ 100 between three bank robbers?
Well, you cannot give $ 33. (3) everyone, $ 0.01 will still have to go nowhere (unless you want them to kill each other).

I only say this because money is not mathematics, and you must be sure of the necessary accuracy.
No more and no less.

+3
source

It is important to use well-defined rounding rules for a specific application. If the billing application indicates that all position amounts will be rounded to the nearest penny, then the total invoice amount should reflect this. If he indicates that all calculations will be carried out to hundredths of a penny, then the invoice should probably reflect this (perhaps formatting fractional pennies in the form of small superscripts, as gas prices do). In some cases, fractional pennies could be distributed among the elements of the account on an ongoing basis, for example.

  old_total = total
   old_rounded_total = rounded_total
   total = total + line_item
   rounded_total = round_to_penny (total)
   displayed_line_item_cost = rounded_total - old_rounded_total

In other cases, you can go around all lines of accounts to the nearest penny, subtract from this amount the sum of all rounded lines of accounts and adjust up or down those lines that are closest to the "penny" border.

If rounding semantics are well defined and the application follows them, the results will exactly match the specification. If semantics are not defined, the results will also not be.

0
source

Source: https://habr.com/ru/post/894123/


All Articles