This question already has answers here:
Using integer instead of decimal
(2 answers)
Closed 9 years ago.
I'm having trouble with a particular homework assignment of mine. It almost seems impossible. The question goes like this...
"In the future, you may work with other programming languages that do not have a type like decimal which supports precise monetary calculations. In those languages, you should perform such calculations using integers. Modify the application to use only integers to calculate the compound interest. Treat all monetary amounts as integral numbers of pennies. Then break the result into its dollars and cents portions by using the division and remainder operations, respectively. Insert a period between the dollars and the cents portions when you display the results."
When I follow the directions and use integers I get these overflow errors before I can even divide anything out. Does anyone have any idea how to make this work? Here's the original code that needs to be modified...
decimal amount; //amount on deposit at end of each year
decimal principal = 1000; //initial amount before interest
double rate = 0.05; //interest rate
//display headers
Console.WriteLine("Year{0,20}", "Amount on deposit");
//calculate amount on deposit for each of ten years
for (int year = 1; year <= 10; year++)
{
//calculate new amount for specified year
amount = principal *
((decimal)Math.Pow(1.0 + rate, year));
//display the year and the amount
Console.WriteLine("{0,4}{1,20:C}", year, amount);
}
This is the code I have so far...
ulong amount; //amount on deposit at end of each year
ulong principal = 100000; //initial amount before interest
ulong rate = 5; //interest rate
ulong number = 100;
//display headers
Console.WriteLine("Year{0,20}", "Amount on deposit");
//calculate amount on deposit for each of ten years
for (int year = 1; year <= 10; year++)
{
//calculate new amount for specified year
amount = principal *
((ulong)Math.Pow(100 + rate, year));
amount /= number;
number *= 10;
//display the year and the amount
Console.WriteLine("{0,4}{1,20}", year, amount);
It gets some of the right numbers, but then starts spitting out zeros for some reason.
You are changing the values of amount and number each time through the loop, but I don't believe that's what you want to do here. If you remove those assignments and change the parameters in your final Console.WriteLine call, (amount / 100 and amount % 100 will be helpful here) you should be able to get the result you are looking for.
((ulong)Math.Pow(100 + rate, year)) Will grow way too fast 105^10 > ulong.
I think teacher ment for them to keep math.pow as a decimal.
amount = (ulong)(Math.Round(principal *
Math.Pow((number + rate)/100.0, year),0));
//display the year and the amount
Console.WriteLine("{0,4}{1,17}.{2,-2}", year, "$" + (ulong)(amount / number), (ulong)(amount % number));
Question just says variables, not constants :) variables would all still be ulong
Related
So I'm currently taking a C# fundamentals course as the entrance stage of a 6 month C# learning program. One of the tasks we have under the "Data Types and Variables" is an interest calculator.
The premise is such: You have a "deposit" that you write in the first line. The deposit has a 5% interest to it. The program needs to output the deposit's value for 3 years, for each year, all at once.
So 100.00, 105.00, 110.25, 115.76. The numbers after the decimal point need to be rounded to 2 digits, as well as "The rules of math for rounding apply here".
double deposit = double.Parse(Console.ReadLine());
double interest = (deposit*5)/100;
double yearOne = deposit + interest;
double yearTwo = yearOne + interest;
double yearThree = yearTwo + interest;
string totalSums = ($"{yearOne:N2}\n{yearTwo:N2}\n{yearThree:N2}\n");
Console.WriteLine( totalSums );
This is the code I've written so far. It SEEMS to work, but it's not as accepted.
If I put the deposit value as 100 (one of the examples), I get this output:
100
105.00
110.00
115.00
I've put the calculation for the interest percentage as double interest = (deposit*5)/100, which checks out if I use an external calculator to test it. But the program doesn't give the right output.
Say if I put 100.23 as the deposit input, I'll get: 105.24, 110.25, 115.26 when I should get 105.24, 110.50, 116.02. However, a round 100.00 doesn't even display the digits after the decimal point, just rounds them down to the whole number.
I thought the problem comes from using double and not decimal due to floating-point precision issues, so I changed everything to decimal. I still get this exact problem. Nothing changes.
I've had other issues that I at least have ideas on where I'm going wrong, but this one has been screwing with me since 3 days. So I resorted to some help here.
Why am I not getting the correct outputs ? Where is my problem coming from ? Is it the math ? Or logic ? Maybe I'm not using the correct method ? I'm at a loss... And the learning resources I've been given don't seem to help me with this issue, too. Like it's the ONLY task that the resources don't help with.
I've also seen other posts about compound interest, but they use arrays and other things that I'm not yet at the point of learning within the program. So code like that isn't gonna pass the automatic tester. I'm not asking for a complete code solving or "cheat" if you will; I just need some guidance on what my issue here is, because I'm clueless at this point.
Your question is about compound interest, not simple interest. Therefore, you need to calculate the new interest every year.
double deposit = double.Parse(Console.ReadLine());
double yearOne = deposit + (deposit * 5)/100;
double yearTwo = yearOne + (yearOne * 5)/100;
double yearThree = yearTwo + (yearTwo * 5)/100;
string totalSums = ($"{yearOne:N2}\n{yearTwo:N2}\n{yearThree:N2}\n");
Console.WriteLine( totalSums );
If you know about loops, you can create a loop over 3 years and update the amount in the account:
static class Program
{
static void Main(string[] args)
{
// set interest rate (fixed)
decimal rate = 5m/100;
// get deposit amount from user
Console.WriteLine("Enter Initial Amount:");
string input = Console.ReadLine();
decimal amount = decimal.Parse(input);
// loop over three years
Console.WriteLine($"{"year"}\t{"amount"}");
for (int year = 1; year <= 3; year++)
{
// calculate interest for the year based on
// current amount in the account
decimal interest = rate * amount;
// deposit interest in account
amount += interest;
Console.WriteLine($"{year}\t{amount:c2}");
}
}
}
with output
Enter Initial Amount:
1000
year amount
1 $1,050.00
2 $1,102.50
3 $1,157.63
you need to recalculate the interest amount each year.
double deposit = double.Parse(Console.ReadLine());
//Use deposit to calculate interest
double yearOneinterest = (deposit*5)/100;
double yearOne = deposit + yearOneinterest;
//Use yearOne amount to calculate interest
double yearTwointerest = (yearOne*5)/100;
double yearTwo = yearOne + yearTwointerest;
//Use yearTwo amount to calculate interest
double yearThreeinterest = (yearTwointerest*5)/100;
double yearThree = yearTwo + yearThreeinterest;
string totalSums = ($"{yearOne:N2}\n{yearTwo:N2}\n{yearThree:N2}\n");
Console.WriteLine( totalSums );
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);
This question already has answers here:
Is there a Math API for Pow(decimal, decimal)
(6 answers)
Closed 7 years ago.
i am still new to learning C# and was wondering if i could get some help. I am writing a program C# and Windows forms so that users can calculate their monthly payments and interest for a mortgage. The equation i have for the payments is:
Payment = p * r / ( 1 - ( 1 + r ) ^ ( -n ) )
Where p is the amount of the loan, r is the monthly interest rate given as a number from 0 (for 0 percent) and 1 (for 100 percent), n is the duration of the loan in months
Then the formula for the total interest paid is: total interest = n * payment –p
Now i have tried entering all of these numbers as doubles using the Math.Pow method for the payments and got incorrect calculations. I am assuming that the rate NEEDS to be a decimal, so when i try them ALL as decimals, VS doesnt like the "^" method or the math.pow method. So my question is, how are you supposed to use decimals with exponents?
For those that wish to see my current code please note that i am just trying to get the calculations finished before i start adding extra 'else' statements.
decimal amnt = Convert.ToDecimal(txtAMNT.Text);
string Amount=Convert.ToString(txtAMNT.Text);
decimal rate = Convert.ToDecimal(txtRATE.Text);
string Rate = Convert.ToString(txtRATE.Text);
decimal time = Convert.ToDecimal(txtTIME.Text);
string Time=Convert.ToString(txtTIME.Text);
decimal monthpay;
decimal totalinterest;
decimal realrate = rate / 100;
if ((Amount == "")||(Rate == "")||(Time==""))
{
MessageBox.Show("Please fill all boxes with numbers");
}
else
{
monthpay=amnt*realrate/(1-(1+realrate)^(-time));
totalinterest=time*monthpay-amnt;
mtbMonPay.Text=monthpay.ToString("c");
mtbTotalInterest.Text=totalinterest.ToString("c");
}
You should use double for this calculation.
The reason you got incorrect results was that you forgot to divide the annual interest rate by 12 to get the monthly interest rate.
Decimal does not support exponentiation. Also, the caret operator (^) is not for exponentiation in C#; there is no exponentiation operator. You just have to call Math.Pow.
See also https://stackoverflow.com/a/6426826/385844
double should be plenty accurate for the precisions you are working with. Try changing all your decimals to doubles.
Another problem is your rate. Real rate is entered value/100, which means 1 which you said meant 100% actually ends up as 1%.
I used to think I understand the difference between decimal and double values, but now I'm not able to justify the behavior of this code snippet.
I need to divide the difference between two decimal numbers in some intervals, for example:
decimal minimum = 0.158;
decimal maximum = 64.0;
decimal delta = (maximum - minimum) / 6; // 10.640333333333333333333333333
Then I create the intervals in reverse order, but the first result is already unexpected:
for (int i = 5; i >= 0; i--)
{
Interval interval = new Interval(minimum + (delta * i), minimum + (delta * (i + 1));
}
{53.359666666666666666666666665, 63.999999999999999999999999998}
I would expect the maximum value to be exactly 64. What am I missing here?
Thank you very much!
EDIT: if I use double instead of decimal it seems to works properly!
You're not missing anything. This is the result of rounding the numbers multiple times internally, i.e. compounding loss of precision. The delta, to begin with, isn't exactly 10.640333333333333333333333333, but the 3s keep repeating endlessly, resulting in a loss of precision when you multiply or divide using this decimal.
Maybe you could do it like this instead:
for (decimal i = maximum; i >= delta; i -= delta)
{
Interval interval = new Interval(i - delta, i);
}
Double has 16 digits precision while Decimal has 29 digits precision. Thus, double is more than likely would round it off than decimal.
I'm having trouble with a particular homework assignment of mine. It almost seems impossible. The question goes like this...
"In the future, you may work with other programming languages that do not have a type like decimal which supports precise monetary calculations. In those languages, you should perform such calculations using integers. Modify the application to use only integers to calculate the compound interest. Treat all monetary amounts as integral numbers of pennies. Then break the result into its dollars and cents portions by using the division and remainder operations, respectively. Insert a period between the dollars and the cents portions when you display the results."
When I follow the directions and use integers I get these overflow errors before I can even divide anything out. Does anyone have any idea how to make this work? Here's the original code that needs to be modified...
decimal amount; //amount on deposit at end of each year
decimal principal = 1000; //initial amount before interest
double rate = 0.05; //interest rate
//display headers
Console.WriteLine("Year{0,20}", "Amount on deposit");
//calculate amount on deposit for each of ten years
for (int year = 1; year <= 10; year++)
{
//calculate new amount for specified year
amount = principal *
((decimal)Math.Pow(1.0 + rate, year));
//display the year and the amount
Console.WriteLine("{0,4}{1,20:C}", year, amount);
}
This is the code I have so far...
long amount; //amount on deposit at end of each year
long principal = 100000; //initial amount before interest
long rate = 5; //interest rate
long number = 100;
//display headers
Console.WriteLine("Year{0,20}", "Amount on deposit");
//calculate amount on deposit for each of ten years
for (int year = 1; year <= 10; year++)
{
//calculate new amount for specified year
amount = principal *
((long)Math.Pow(100 + rate, year));
amount /= number;
number *= 10;
//display the year and the amount
Console.WriteLine("{0,4}{1,20}", year, amount);
It gets some of the right numbers, but then starts spitting out negative numbers for some reason.
Just to give you a hint:
int amount;
//...some code...
//let's pretend we have an amount of 100.97
amount = (int)(100.97 * 100); // amount = 10097
Math.Pow uses double. It does not use long.
In the following line you are implictly casting your rate and year to double.
amount = principal *
((long)Math.Pow(100 + rate, year));
So you are effectly doing this:
double dRate = (double)(100 + rate);
double dYear = (double)year;
double dPow = Math.Pow(dRate, dYear);
amount = principal * (long)dPow;
If you want your Pow function to really use long then you probably need to write it yourself.