Hi I am trying to create a amortization schedule , which shows the EMI , Principal , Interest and the new Principal for next month. The problem is that the monthly principal instead of increasing keeps on decreasing. As far as from searching the net , I am doing the right calculations. What am I missing?
decimal principal = 312500;
decimal rate = 3.50M;
decimal EMI;
decimal monthlyInterest;
decimal monthlyPrincipal;
decimal newPrincipalBalance;
decimal downPayment = 62500;
decimal actualPrincipal = principal - downPayment;
for (int i = 0; i <= 24; i++)
{
Console.WriteLine("principal " + actualPrincipal);
EMI = Math.Round(monthlyPayments(actualPrincipal, rate, 30));
Console.WriteLine("EMI " + EMI);
monthlyInterest = actualPrincipal * rate / 12;
monthlyInterest = Math.Round((actualPrincipal * rate / 100) / 12);
Console.WriteLine("monthlyInterest " + monthlyInterest);
monthlyPrincipal = Math.Round(EMI - monthlyInterest);
Console.WriteLine("monthlyPrincipal " + monthlyPrincipal);
newPrincipalBalance = Math.Round(actualPrincipal - monthlyPrincipal);
Console.WriteLine("newPrincipalBalance " + newPrincipalBalance);
Console.WriteLine("===================================");
actualPrincipal = newPrincipalBalance;
}
}
public static decimal monthlyPayments(decimal actualPrincipal, decimal rate, int years)
{
rate = rate / 1200;
years = years * 12;
decimal F = (decimal)Math.Pow((double)(1 + rate), years);
return actualPrincipal * (rate * F) / (F - 1);
}
These are first few of my results where the monthly principal is decreasing
This is what the expected result is :
This is the formula for calculating the monthlyPayments
I found what I was doing wrong. As the EMI remains fixed for the entire period of the loan, it should have been kept outside the loop.
Console.WriteLine("principal " + actualPrincipal);
EMI = Math.Round(monthlyPayments(actualPrincipal, rate, 30));
Console.WriteLine("EMI " + EMI);
for (int i = 0; i <= 24; i++)
{
monthlyInterest = actualPrincipal * rate / 12;
monthlyInterest = Math.Round((actualPrincipal * rate / 100) / 12);
Console.WriteLine("monthlyInterest " + monthlyInterest);
monthlyPrincipal = Math.Round(EMI - monthlyInterest);
Console.WriteLine("monthlyPrincipal " + monthlyPrincipal);
newPrincipalBalance = Math.Round(actualPrincipal - monthlyPrincipal);
Console.WriteLine("newPrincipalBalance " + newPrincipalBalance);
Console.WriteLine("===================================");
actualPrincipal = newPrincipalBalance;
}
Related
Setting up a fairly simple undetermined linear system solution using Google OrTools (in c#). I'm having trouble constraining certain values to whole numbers. In the following code example, I'd like variables a,b,c, and d to be whole numbers, but cash1 and cash2 as doubles. Please ignore the poor variable naming!
Code:
// setup
double VTI = 221.17;
double BND = 81.92;
double CASH = 1;
double account1 = 10000;
double account2 = 5000;
double total = account1 + account2;
// allocation
var VTIAmount = total * .8;
var BNDAmount = total * .2;
var solver = Solver.CreateSolver("GLOP");
// variables
var a = solver.MakeIntVar(0.0, int.MaxValue, "a");
var b = solver.MakeIntVar(0.0, int.MaxValue, "b");
var cash1 = solver.MakeNumVar(0.0, double.MaxValue, "cash1");
var c = solver.MakeIntVar(0.0, int.MaxValue, "c");
var d = solver.MakeIntVar(0.0, int.MaxValue, "d");
var cash2 = solver.MakeNumVar(0.0, double.MaxValue, "cash2");
// constraints
solver.Add(a * VTI + b * BND + cash1 * CASH == account1);
solver.Add(c * VTI + d * BND + cash2 * CASH == account2);
solver.Add(a * VTI + c * VTI == VTIAmount);
solver.Add(b * BND + d * BND == BNDAmount);
// objective function
solver.Maximize(d);
// solve
solver.Solve();
// results
Console.WriteLine("Solution:");
Console.WriteLine("Objective value = " + solver.Objective().Value());
Console.WriteLine("a = " + a.SolutionValue());
Console.WriteLine("b = " + b.SolutionValue());
Console.WriteLine("c = " + c.SolutionValue());
Console.WriteLine("d = " + d.SolutionValue());
Console.WriteLine("cash1 = " + cash1.SolutionValue());
Console.WriteLine("cash2 = " + cash2.SolutionValue());
Output:
Solution:
Objective value = 36.62109375
a = 45.21408871004205
b = 0
c = 9.04281774200841
d = 36.62109375
cash1 = 0
cash2 = 0
Changing the code snippets in the OG post to:
var solver = Solver.CreateSolver("SCIP");
And this:
solver.Add(a * VTI + c * VTI >= VTIAmount*.99);
solver.Add(b * BND + d * BND >= BNDAmount*.99);
// objective function
solver.Maximize(d-cash1-cash2);
Solves the solution fairly elegantly:
Solution:
Objective value = 8.22
a = 44
b = 3
c = 10
d = 34
cash1 = 22.760000000000446
cash2 = 3.019999999999982
I'm trying to create a booking form in C#, where a user can select multiple tickets for one or more attraction site. They can also add a promotion code for a 10% discount on the total price if the code contains an "X". I'm having trouble with calculating the total price before the promotion discount can be taken away. I thought I could make the default value of each attraction "0" so when the individual prices are added for dblPrice, but that doesn't work.
Here's what I have so far -
//declared variables
double dblPrice;
double dblDiscount;
double dblRollprice, dblWaterprice, dblKidsprice, dblLiveprice, dblActionprice, dblThrillprice, dbl4dprice;
double dblTotalprice;
string strRollquantity, strWaterquantity, strKidsquantity, strLivequantity, strActionquantity, strThrillquantity, str4dquantity;
int intWaterquantity, intRollquantity, intKidsquantity, intLivequantity, intActionquantity, intThrillquantity, int4dquantity;
string strPromocode;
strPromocode = txtPromocode.Text;
strRollquantity = txtRollquantity.Text;
strWaterquantity = txtWaterquantity.Text;
strKidsquantity = txtKidsquantity.Text;
strLivequantity = txtLivequantity.Text;
strActionquantity = txtActionquantity.Text;
strThrillquantity = txtThrillquantity.Text;
str4dquantity = txt4dquantity.Text;
int.TryParse(strRollquantity, out intRollquantity);
int.TryParse(strWaterquantity, out intWaterquantity);
int.TryParse(strKidsquantity, out intKidsquantity);
int.TryParse(strLivequantity, out intLivequantity);
int.TryParse(strActionquantity, out intActionquantity);
int.TryParse(strThrillquantity, out intThrillquantity);
int.TryParse(str4dquantity, out int4dquantity);
dblRollprice = 15.00;
dblWaterprice = 15.00;
dblActionprice = 15.00;
dblKidsprice = 15.00;
dblLiveprice = 15.00;
dbl4dprice = 15.00;
dblThrillprice = 15.00;
if (chkRoll.Checked)
{
dblRollprice = dblRollprice * intRollquantity;
}
if (chkWater.Checked)
{
dblWaterprice = dblWaterprice * intWaterquantity;
}
if (chkKids.Checked)
{
dblKidsprice = 15.00 * intKidsquantity;
}
if (chkLive.Checked)
{
dblLiveprice = 15.00 * intLivequantity;
}
if (chkAction.Checked)
{
dblActionprice = 15.00 * intActionquantity;
}
if (chkThrill.Checked)
{
dblThrillprice = 15.00 * intThrillquantity;
}
if (chk4d.Checked)
{
dbl4dprice = 15.00 * int4dquantity;
}
dblPrice = dblRollprice + dblWaterprice + dblThrillprice + dblLiveprice + dblActionprice + dbl4dprice + dblKidsprice;
if (strPromocode == "X")
{
dblDiscount = dblPrice / 100 * 10;
dblTotalprice = dblPrice - dblDiscount;
Response.Write("Price is: " + dblTotalprice + "<br />");
}
I have created a form to arrange a ship hold.
Problem: On multiple times through, it comes back with the decimal point shifted two more spaces. How do I keep it from shifting further?
Code Snippet:
private void btnGetInv_Click(object sender, EventArgs e)
{
//if this is a ship hold, roll percentile to get how much of the ship's total weight capacity is being carried.
if(ShipHold==true)
{
decimal Percentage = 0;
decimal HoldWeight = 0;
LoNum = 1;
HiNum = 100;
DieResult = 0;
Percentage = DieResult + 1 + RollDice.Next(LoNum - 1, HiNum);
WeightAvail = Percentage / 100 * WeightAvail;
HoldWeight = WeightAvail;
RTBItems.Text = "percentage of weight = " + HoldWeight + "\r\n" + RTBItems.Text;
}
WeightAvail is also a decimal. However; LoNum, HiNum, and DieResult are all types int to work with the Random.Next function. It might be best if I can round to the nearest whole number. I'm using Visual Studio 2019.
This was my fix:
HoldWeight = Percentage / 100 * WeightAvail;
//HoldWeight = WeightAvail;
RTBItems.Text = "percentage of weight = " + HoldWeight + "\r\n" + RTBItems.Text;
HoldWeight = 0;
How can I use a Fast Magnitude calculation for 3 values (instead of using square root)? (+/- 3% is good enough)
public void RGBToComparison(Color32[] color)
{
DateTime start = DateTime.Now;
foreach (Color32 i in color)
{
var r = PivotRgb(i.r / 255.0);
var g = PivotRgb(i.g / 255.0);
var b = PivotRgb(i.b / 255.0);
var X = r * 0.4124 + g * 0.3576 + b * 0.1805;
var Y = r * 0.2126 + g * 0.7152 + b * 0.0722;
var Z = r * 0.0193 + g * 0.1192 + b * 0.9505;
var LB = PivotXyz(X / 95.047);
var AB = PivotXyz(Y / 100);
var BB = PivotXyz(Z / 108.883);
var L = Math.Max(0, 116 * AB - 16);
var A = 500 * (LB - AB);
var B = 200 * (AB - BB);
totalDifference += Math.Sqrt((L-LT)*(L-LT) + (A-AT)*(A-AT) + (B-BT)*(B-BT));
}
totalDifference = totalDifference / color.Length;
text.text = "Amount of Pixels: " + color.Length + " Time(MilliSeconds):" + DateTime.Now.Subtract(start).TotalMilliseconds + " Score (0 to 100)" + (totalDifference).ToString();
RandomOrNot();
}
private static double PivotRgb(double n)
{
return (n > 0.04045 ? Math.Pow((n + 0.055) / 1.055, 2.4) : n / 12.92) * 100.0;
}
private static double PivotXyz(double n)
{
return n > 0.008856 ? CubicRoot(n) : (903.3 * n + 16) / 116;
}
private static double CubicRoot(double n)
{
return Math.Pow(n, 1.0 / 3.0);
}
This is the important part: totalDifference += Math.Sqrt((L-LT)*(L-LT) + (A-AT)*(A-AT) + (B-BT)*(B-BT));
I know there are FastMagnitude calculations online, but all the ones online are for two values, not three. For example, could i use the difference between the values to get a precise answer? (By implementing the difference value into the equation, and if the difference percentage-wise is big, falling back onto square root?)
Adding up the values and iterating the square root every 4 pixels is a last resort that I could do. But firstly, I want to find out if it is possible to have a good FastMagnitude calculation for 3 values.
I know I can multi-thread and parllelize it, but I want to optimize my code before I do that.
If you just want to compare the values, why not leave the square root out and work with the length squared?
Or use the taylor series of the square root of 1+x and cut off early :)
My goal is to use GPS to measure the distance that I moved with my phone. My problem is, that the results are imprecise. I've used the following code to calculate the distance:
public double getDistance(GeoCoordinate p1, GeoCoordinate p2)
{
double d = p1.Latitude * 0.017453292519943295;
double num3 = p1.Longitude * 0.017453292519943295;
double num4 = p2.Latitude * 0.017453292519943295;
double num5 = p2.Longitude * 0.017453292519943295;
double num6 = num5 - num3;
double num7 = num4 - d;
double num8 = Math.Pow(Math.Sin(num7 / 2.0), 2.0) + ((Math.Cos(d) * Math.Cos(num4)) * Math.Pow(Math.Sin(num6 / 2.0), 2.0));
double num9 = 2.0 * Math.Atan2(Math.Sqrt(num8), Math.Sqrt(1.0 - num8));
return (6376500.0 * num9);
}
This is my OnLocationChanged implementation:
bool begin = true;
public void OnLocationChanged(Location location)
{
_aktuellerOrt = location;
//aktuellerOrt.Speed is always 0, so I cannot use that.
if (_aktuellerOrt == null)
{
//message
}
else
{
if (_aktuellerOrt.Accuracy > 70) //I found values around 130 to be more or less good
{
_locationText.Text = String.Format("{0}, {1}", _aktuellerOrt.Latitude, _aktuellerOrt.Longitude);
GeoJetzt = new GeoCoordinate();
GeoJetzt.Latitude = _aktuellerOrt.Latitude;
GeoJetzt.Longitude = _aktuellerOrt.Longitude;
if (beginn)
{
GeoVorher = new GeoCoordinate();
GeoVorher.Latitude = _aktuellerOrt.Latitude;
GeoVorher.Longitude = _aktuellerOrt.Longitude;
beginn = false;
}
else
{
double abstand = getDistance(GeoVorher, GeoJetzt);
weg += abstand;
if (weg >= 1)
_distanzText.Text = weg + " kilometers";
else
_distanzText.Text = (weg * 1000) + " meters";
_distanzText.Text += " (" + abstand + ", " + _aktuellerOrt.Accuracy + ")";
GeoVorher = new GeoCoordinate();
GeoVorher.Latitude = _aktuellerOrt.Latitude;
GeoVorher.Longitude = _aktuellerOrt.Longitude;
}
}
else
_locationText.Text = "Too coarse, now " + _aktuellerOrt.Accuracy + ".";
}
}
The problem is, I get values for abstand within the kilometer range while not moving the phone.
What are best practices for imprecise signals? My goal is to measure the distance while jogging or running, so 10 - 16 km/h.