Compound Interest Calculation - c#

I have this C# code which calculate compound interest plus principal amount every year.
static void CompoundInterest(double principal, double interestRate, double years, double annualCompound)
{
var total = 0.0;
for (int t = 1; t < years + 1; t++)
{
total = principal * Math.Pow((1 + interestRate / annualCompound),
(annualCompound * t));
Console.Write("Your Total for Year {0} "
+ "is {1}. \n", t, total);
}
}
When I tested it with
CompoundInterest(1000, 0.05, 3, 12);
and the output is
Your Total for Year 1 is 1051.161897881733.
Your Total for Year 2 is 1104.941335558327.
Your Total for Year 3 is 1161.4722313334678.
How should I round it accurately? Another question is Math.Pow uses double but in financial calculation, we need decimal. How do I fix this? Convert into decimal after Math.Pow?

I made some test by rounding first and converting to decimal and by converting to decimal and then rounding afterword. Both gave the same results.
But from the logic point of view, I would convert first than rounding after words. This way I will have better control of testing what is converted and what is rounded.
For converting there are different answers, but I found this method Convert.ToDecimal is supported by all .net frameworks and cores.
ex. decimal value = Convert.ToDecimal(double_value);
And then you decimal.Round, which some one has asked and got answer here Why does .NET use banker's rounding as default?
Just in case reference to Floating-point numeric types.

You can convert a double to a decimal directly if you'd like
decimal decimalTotal = (decimal)total;
As for rounding, there is a built-in function, Math.Round, that takes a variety of number formats. It has a overload to specify how many decimal points you want.
decimal roundedDecimal = Math.Round(decimalTotal, 2);

Related

Extract the number after the decimal ponit in c# [duplicate]

This question already has answers here:
Double vs Decimal Rounding in C#
(2 answers)
Closed 5 years ago.
I should write a program that the input is double (variable called money), and I should print separately the digits before the decimal point and the digits after.
for example:
for the input: 36.5 should print: The number before the decimal point is: 36 The number after decimal point is: 5
for the input: 25.4 should print: The number before the decimal point is: 24 The number after decimal point is: 4
Console.WriteLine("Enter money:");
double money = double.Parse(Console.ReadLine());
int numBeforePoint = (int)money;
double numAfterPoint = (money - (int)money)*10;
Console.WriteLine("The number beforethe decimal point is: {0}. the number after the decimal point is: {1}",numBeforePoint,numAfterPoint);
If I enter 25.4 it prints: The number before the decimal point is: 24 The number after decimal point is: 3.9999999
I don't want 3.999999 I want 4
You should use decimal to represent numeric types, rather than doubles - it's what they were designed for!
You've been the victim of a floating point error, where the value you're assigning to a floating point value can't be exactly represented with its precision (the .999... you get is the closest value it can represent).
decimals have a lower range than doubles, but much higher precision - this means they're more likely to be able to represent the values you're assigning. See here or the linked decimal documentation page for more details.
Note that a more conventional way of getting the decimal part involves Math.Truncate (which by the way will work for negative values as well):
decimal numAfterPoint = (money - Math.Truncate(money))*10;
Probably easiest to use the string representation of the decimal, and use substring before and after the index of '.'
Something like this:
string money = Console.ReadLine();
int decimalIndex = money.IndexOf('.');
string numBeforePoint = money.Substring(0, decimalIndex);
string numAfterPoint = money.Substring(decimalIndex + 1);
Then you can parse the string representations as needed.
Try this:
static string Foo(double d)
{
var str = d.ToString(CultureInfo.InvariantCulture).Split('.');
var left = str[0];
var right = str[1];
return $"The number before the decimal point is: {left} The number after decimal point is: {right}";
}
using System.Linq;
public static string GetDecimalRemainder(double d)
{
return d.ToString(CultureInfo.InvariantCulture).Split('.').Last();
{
Using LINQ is much more convenient in my opinion.

Float wrong calculation [duplicate]

This question already has answers here:
Why am I getting the wrong result when using float? [duplicate]
(4 answers)
Float is converting my values
(4 answers)
Closed 9 years ago.
The result must be 806603.77 but why I get 806603.8 ?
float a = 855000.00f;
float b = 48396.23f;
float res = a - b;
Console.WriteLine(res);
Console.ReadKey();
You should use decimal instead because float has 32-bit with 7 digit precision only that is why the result differs, on other hand decimal has 128-bit with 28-29 digit precision.
decimal a = 855000.00M;
decimal b = 48396.23M;
decimal res = a - b;
Console.WriteLine(res);
Console.ReadKey();
Output: 806603.77
A float (also called System.Single) has a precision equivalent to approximately seven decimal figures. Your res difference needs eight significant decimal digits. Therefore it is to be expected that there is not enough precision in a float.
ADDITION:
Some extra information: Near 806,000 (806 thousand), a float only has four bits left for the fractional part. So for res it will have to choose between
806603 + 12/16 == 806603.75000000, and
806603 + 13/16 == 806603.81250000
It chooses the first one since it's closest to the ideal result. But both of these values are output as "806603.8" when calling ToString() (which Console.WriteLine(float) does call). A maximum of 7 significant decimal figures are shown with the general ToString call. To reveal that two floating-point numbers are distinct even though they print the same with the standard formatting, use the format string "R", for example
Console.WriteLine(res.ToString("R"));
Because float has limited precision (32 bits). Use double or decimal if you want more precision.
Please be aware that just blindly using Decimal isn't good enough.
Read the link posted by Oded: What Every Computer Scientist Should Know About Floating-Point Arithmetic
Only then decide on the appropriate numeric type to use.
Don't fall into the trap of thinking that just using Decimal will give you exact results; it won't always.
Consider the following code:
Decimal d1 = 1;
Decimal d2 = 101;
Decimal d3 = d1/d2;
Decimal d4 = d3*d2; // d4 = (d1/d2) * d2 = d1
if (d4 == d1)
{
Console.WriteLine("Yay!");
}
else
{
Console.WriteLine("Urk!");
}
If Decimal calculations were exact, that code should print "Yay!" because d1 should be the same as d4, right?
Well, it doesn't.
Also be aware that Decimal calculations are thousands of times slower than double calculations. They are not always suitable for non-currency calculations (e.g. calculating pixel offsets or physical things such as velocities, or anything involving transcendental numbers and so on).

two decimal places for decimal/money field

I have a table with money field in my database. I have created entity and created decimal property for that money field. When the value of that field is displayed on My MVC3 view, It has four zeros 0000 after decimal like this : 5489.0000. I want to show only two 00 or decimal places. How can I fix it. Why it is showing four decimal places even I declared property as decimal.
Please suggest.
The SQL Server money datatype internally is a 64-bit integer with an implied scale of 4 decimal places. To quote Books Online, it is accurate "to ten-thousandsth of a currency unit." It is, the rough equivalent of a decimal(19,4).
The reason for the scale of 4 rather than 2 is to maintain precision in the results of arithmetic. Your ordinary currency value has a scale of 2 (e.g. $3.27) Multiplication or division of two numbers scaled to 2 decimal places gives a results that is precise to 4 decimal places: 9.23 divided by 3.27 yields a result of 2.82262996941896 (approximately). You can carry the result to whatever accuracy (number of decimal places) you desire. However, the result is only precise to 4 decimal places (2.8226) as the original values were only precise to 2 decimal places. That measurement is precise to within 1/2 of the smallest unit specified (+/- 0.005).
But I digress.
As a result of a SQL Server money value having an implied scale of 4, ADO.Net converts the value to a System.Decimal with a scale of 4. And since System.Decimal tracks scale, when you convert it to string, you get 4 decimal places.
To get fewer, you can
Round it before conversion, using the appropriate Decimal.Round() overload, or
Format it as desired (eg. (3.27M).ToString("0.00") ;.
Hope this helps.
This program:
namespace Sandbox
{
using System ;
class Program
{
static void Main( string[] args )
{
decimal pi = (decimal) Math.PI ;
string piText = pi.ToString("0.00");
Console.WriteLine("PI to 2 decimal places is {0} one way, and {1:0.00} another" , piText , pi ) ;
return;
}
}
}
Produces what you'd expect:
PI to 2 decimal places is 3.14 one way, and 3.14 another
Cheers,
N.
You have to format the string.
One thing you can do if it money you want to display is:
static void Main ()
{
decimal x = 0.999m;
decimal y = 9999999999999999999999999999m;
Console.WriteLine("My amount = {0:C}", x);
Console.WriteLine("Your amount = {0:C}", y);
}
}
OUTPUT:
Output
My amount = $1.00
Your amount = $9,999,999,999,999,999,999,999,999,999.00
the {0:C} is the currency Format
Hope this helps!
Here is everything you need to know about formatting strings.
http://blog.stevex.net/string-formatting-in-csharp/
I used this and it worked:
YourDecField.ToString("N")

How to convert decimal to string value for dollars and cents separated in C#?

I need to display decimal money value as string, where dollars and cents are separate with text in between.
123.45 => "123 Lt 45 ct"
I came up with the following solution:
(value*100).ToString("#0 Lt 00 ct");
However, this solution has two drawbacks:
Upon showing this solution to a fellow programmer, it appears to be unintuitive and requires some explaining.
Cents are allways displayed as two digits. (Not real problem for me, as currently this is how I need it to be displayed.)
Is there any alternative elegant and simple solution?
This is a fairly simple operation. It should be done in a way, that your fellow programmers understand instantly. Your solution is quite clever, but cleverness is not needed here. =)
Use something verbose like
double value = 123.45;
int dollars = (int)value;
int cents = (int)((value - dollars) * 100);
String result = String.Format("{0:#0} Lt {1:00} ct", dollars, cents);
I had some errors with accepted answer above (it would drop my result one penny)
Here is my correction
double val = 125.79;
double roundedVal = Math.Round(val, 2);
double dollars = Math.Floor(roundedVal);
double cents = Math.Round((roundedVal - dollars), 2) * 100;
This might be a bit over the top:
decimal value = 123.45M;
int precision = (Decimal.GetBits(value)[3] & 0x00FF0000) >> 16;
decimal integral = Math.Truncate(value);
decimal fraction = Math.Truncate((decimal)Math.Pow(10, precision) * (value - integral));
Console.WriteLine(string.Format("{0} Lt {1} ct", integral, fraction));
The format of the decimal binary representation is documented here.

Double Precision

I have a code, and I do not understand it. I am developing an application which precision is very important. but it does not important for .NET, why? I don't know.
double value = 3.5;
MessageBox.Show((value + 1 * Math.Pow(10, -20)).ToString());
but the message box shows: 3.5
Please help me, Thank you.
If you're doing anything where precision is very important, you need to be aware of the limitations of floating point. A good reference is David Goldberg's "What Every Computer Scientist Should Know About Floating-Point Arithmetic".
You may find that floating-point doesn't give you enough precision and you need to work with a decimal type. These, however, are always much slower than floating point -- it's a tradeoff between accuracy and speed.
You can have precision, but it depends on what else you want to do. If you put the following in a Console application:
double a = 1e-20;
Console.WriteLine(" a = {0}", a);
Console.WriteLine("1+a = {0}", 1+a);
decimal b = 1e-20M;
Console.WriteLine(" b = {0}", b);
Console.WriteLine("1+b = {0}", 1+b);
You will get
a = 1E-20
1+a = 1
b = 0,00000000000000000001
1+b = 1,00000000000000000001
But Note that The Pow function, like almost everything in the Math class, only takes doubles:
double Pow(double x, double y);
So you cannot take the Sine of a decimal (other then by converting it to double)
Also see this question.
Or use the Decimal type rather than double.
The precision of a Double is 15 digits (17 digits internally). The value that you calculate with Math.Pow is correct, but when you add it to value it just is too small to make a difference.
Edit:
A Decimal can handle that precision, but not the calculation. If you want that precision, you need to do the calculation, then convert each value to a Decimal before adding them together:
double value = 3.5;
double small = Math.Pow(10, -20);
Decimal result = (Decimal)value + (Decimal)small;
MessageBox.Show(result.ToString());
Double precision means it can hold 15-16 digits. 3.5 + 1e-20 = 21 digits. It cannot be represented in double precicion. You can use another type like decimal.

Categories

Resources