Bank interest calculator - c#

I'm trying to make a calculator for interest in bank, like how many years would it take for 1$ to turn into 15$ with 4% interest, but all i get is the same number over and over, but i need it to go higher each year, like 1st year: 1$ * 4%interest, and 2nd year: 4% interest * 1st year interest, and 3rd year: 4% interest* 2nd year interest, and so on until it hits 15$
private void btreikna_Click(object sender, RoutedEventArgs e)
{
double vextir4 = 0.04;
double vextir8 = 0.08;
double vextir12 = 0.12;
double vextir16 = 0.16;
double vextir20 = 0.2;
double startvextir = Convert.ToDouble(byrjunisk.Text);
double artal = Convert.ToDouble(tbartal.Text);
double plusplus = vextir4 * startvextir;
double count = artal;
List<int> listfullofints = new List<int>();
for (int i = 0; i < artal; i++)
{
int[i]utkoma = plusplus * artal;
}

Your code is not very clear, but what you probably want is something like this:
decimal target = 15;
decimal start = 1;
decimal interest = 0.04M;
decimal currentCapital = start;
var numOfYears = 0;
while (currentCapital < target)
{
currentCapital = currentCapital + currentCapital*interest;
numOfYears++;
}
Console.WriteLine(currentCapital + " in " + numOfYears);
Few notes about that code and your attempt. It is advised to use decimal for precise calculations (and you want to be precise with money :) ) In your code you are not updating your plusplus variable - it is always the very first interest. And the last note - you cant use for loop as you dont know ahead of time the number of executions.

The classical formula for compound interest is:
V = (1 + r) ^ t
Where V is future value (or final number/original number), r is interest rate, and t is time.
Thus, in your case: V = 15 (from 15/1), r = 0.04, find t. Or, in other words:
t = log (V) / log (1 + r)
I recommend you to use Math.Log method.
double t = Math.Log(15D) / Math.Log(1.04D);
To get the time t you look for (without for loop). You may also be interested to look at the link JleruOHeP provides for interest calculation.

Related

CS0266 error in C#. Need advise with adding int and double together.

{
int priceforprimer = 0;
double H, L, W, Finthearea = 0;
priceforprimer = int.Parse(textBox9.Text);
H = double.Parse(textBox5.Text);
L = double.Parse(textBox6.Text);
W = double.Parse(textBox7.Text);
Finthearea = H * L * W;
priceforprimer = Finthearea / 13;
textBox8.Text = Finthearea.ToString();
Hello, my assignment is to work out the area of the wall and then work out how many tins of primer is needed for that wall exactly as "Paint is purchased as full tins of paint only." The double values work and I can calculate the area, but the division doesn't. Per 13m of wall works out as one tin of primer. I have been trying for 2 hours with this, but I am lost, also pretty new to C# which makes it trickier. Thanks.
//These are typical ceiling samples in C#. You also need to adopt naming //conventions in your code (i.e names like textbox5 are not standard)
using System;
class Program
{
static void Main()
{
// Get ceiling of double value.
double value1 = 123.456;
double ceiling1 = Math.Ceiling(value1);
// Get ceiling of decimal value.
decimal value2 = 456.789M;
decimal ceiling2 = Math.Ceiling(value2);
// Get ceiling of negative value.
double value3 = -100.5;
double ceiling3 = Math.Ceiling(value3);
// Write values.
Console.WriteLine(value1);
Console.WriteLine(ceiling1);
Console.WriteLine(value2);
Console.WriteLine(ceiling2);
Console.WriteLine(value3);
Console.WriteLine(ceiling3);
}
}

Something is wrong with the accuracy of calculation between variables

I have some problems with my code where I think the accuracy is a bit off. I'll take out the declarations of variables from my code, so the code is as small as possible:
int a = Int32.Parse(tb_weight.Text);
double b = 0;
b = (a * 1.03) / 1000;
double g = 0;
g = (1.09 + (0.41 * (Math.Sqrt(50 / b))));
lbl_vertforce.Content = Math.Round((b * g * 9.81), 2);
So, tb_weight is a textbox where the input is made, and lets say the input is 5000, the label lbl_vertforce is showing 119,61 and according to my calculator, it should show 119,74. What is wroing here?
Doubles are not 100% precise and can vary in the least common digits. If you want exact precision you need to use Decimal type which has a bigger memory foot print, but was designed to be very precise. Unfortunately Math.Sqrt is not overloaded for Decimal and only works on doubles. I have provide code I found in another posting discussing the subject of Decimal Square roots: Performing Math operations on decimal datatype in C#?
public void YourCodeModifiedForDecimal()
{
int a = Int32.Parse(tb_weight.Text);
decimal b = 0;
b = (a* 1.03m) / 1000m;
decimal g = 0;
g = (1.09m + (0.41m * (Sqrt(50m / b))));
lbl_vertforce.Content = Math.Round((b* g * 9.81m), 2);
}
public static decimal Sqrt(decimal x, decimal? guess = null)
{
var ourGuess = guess.GetValueOrDefault(x / 2m);
var result = x / ourGuess;
var average = (ourGuess + result) / 2m;
if (average == ourGuess) // This checks for the maximum precision possible with a decimal.
return average;
else
return Sqrt(x, average);
}
You need to round g to 2 decimal places to get 119.74 in the final calculation.
g = Math.Round(1.09 + (0.41 * (Math.Sqrt(50 / b))), 2);

Calculate discount price

I want to make my application to calculate a discount price. This is how I find my discount price, but I have a little problem (logic problem):
private void UpdateDiscount(object sender, EventArgs e)
{
decimal actualPrice = 0;
decimal discount = 0;
int calculateDiscount = 0;
int totalDiscount = 0;
int afterDiscount = 0;
int totalAfterDiscount = 0;
int total = 0;
if (numericTextBox1.TextLength == 6)
{
this.numericUpDown2.Enabled = true;
discount = Convert.ToInt32(this.numericUpDown2.Value);
calculateDiscount = Convert.ToInt32(discount / 100);
totalDiscount = calculateDiscount;
if (!string.IsNullOrEmpty(this.numericTextBox3.Text.ToString()))
{
actualPrice = Convert.ToDecimal(this.numericTextBox3.Text);
}
else
{
numericTextBox3.Text = "";
}
afterDiscount = Convert.ToInt32(actualPrice * totalDiscount);
totalAfterDiscount = Convert.ToInt32(actualPrice);
total = Convert.ToInt32(totalAfterDiscount - afterDiscount);
if (numericUpDown2.Value > 0)
{
this.numericTextBox6.Text = total.ToString();
}
}
else if (numericTextBox1.TextLength != 6)
{
this.numericUpDown2.Enabled = false;
this.numericUpDown2.Value = 0;
this.numericTextBox6.Text = "";
}
else
{
actualPrice = 0;
discount = 0;
calculateDiscount = 0;
totalDiscount = 0;
afterDiscount = 0;
totalAfterDiscount = 0;
total = 0;
MessageBox.Show("There is no data based on your selection", "Error");
}
}
This is the result, the total after discount still same with the total price, even though I already give it discount value.
Given
a price P such that 0 <= P, and
a discount percentage D such that 0 <= D <= 100
you can compute the discount (markdown) MD that needs to be applied as
MD = P * (D/100)
You can then get the discounted price DP as
DP = P - MD
Given that, this should do you:
public static class DecimalHelpers
{
public static decimal ComputeDiscountedPrice( this decimal originalPrice , decimal percentDiscount )
{
// enforce preconditions
if ( originalPrice < 0m ) throw new ArgumentOutOfRangeException( "originalPrice" , "a price can't be negative!" ) ;
if ( percentDiscount < 0m ) throw new ArgumentOutOfRangeException( "percentDiscount" , "a discount can't be negative!" ) ;
if ( percentDiscount > 100m ) throw new ArgumentOutOfRangeException( "percentDiscount" , "a discount can't exceed 100%" ) ;
decimal markdown = Math.Round( originalPrice * ( percentDiscount / 100m) , 2 , MidpointRounding.ToEven ) ;
decimal discountedPrice = originalPrice - markdown ;
return discountedPrice ;
}
}
Don't use int (or Convert.ToInt32) when dealing with money.
See this
decimal discount = 10;
var calculateDiscount = Convert.ToInt32(discount / 100);
MessageBox.Show(calculateDiscount.ToString());
calculateDiscount will be 0 because 0.1 will be converted 0.
I suspect the problem is mostly due to the fact that you're using integers for everything. In particular, these two lines:
discount = Convert.ToInt32(this.numericUpDown2.Value);
calculateDiscount = Convert.ToInt32(discount / 100);
When you use 10 for "10%" as the discount, the second line there is actually resulting in a zero. This is because you are doing integer mathematics: integers can only be whole numbers, and when they have a number that is not whole they truncate it. In this case, discount / 100 in your example would be 0.1, which would get truncated to zero.
Instead of using int, I recommend using decimal for all financial transactions. I would replace most of your integer variable types throughout that function with decimal.
I think you're going to have problems with...
calculateDiscount = Convert.ToInt32(discount / 100);
Int (Integers) are whole numbers, they will be rounded down. If discount is less than 100 it will always be zero.
Avoid using double or floats for financial transactions as they can produce considerable floating point errors.
Using integers is good, as they are accurate and quick, HOWEVER you MUST always consider how numbers will be rounded, ensure the operands and results are always whole numbers.
If they are not whole numbers use the Decimal structure, which under the covers is comprised of three integers, but three times slower than using integers.
In most cases being 3 times slower than blindingly quick, still ends up being blindingly quick so when in doubt use Decimals.
if you want to get the Original Price from the Discounted Price and Discount Value. you can use this code
using System;
public class Program
{
public static void Main()
{
decimal discountedPrice = 280;
decimal discount = (decimal)0.20;
decimal originalPrice = discountedPrice / (decimal)(1-discount);
Console.WriteLine(originalPrice);
}
}```

How do I round doubles in human-friendly manner in C#?

In my C# program I have a double obtained from some computation and its value is something like 0,13999 or 0,0079996 but this value has to be presented to a human so it's better displayed as 0,14 or 0,008 respectively.
So I need to round the value, but have no idea to which precision - I just need to "throw away those noise digits".
How could I do that in my code?
To clarify - I need to round the double values to a precision that is unknown at compile time - this needs to be determined at runtime. What would be a good heuristic to achieve this?
You seem to want to output a value which is not very different to the input value, so try increasing numbers of digits until a given error is achieved:
static double Round(double input, double errorDesired)
{
if (input == 0.0)
return 0.0;
for (int decimals = 0; decimals < 17; ++decimals)
{
var output = Math.Round(input, decimals);
var errorAchieved = Math.Abs((output - input) / input);
if (errorAchieved <= errorDesired)
return output;
}
return input;
}
}
static void Main(string[] args)
{
foreach (var input in new[] { 0.13999, 0.0079996, 0.12345 })
{
Console.WriteLine("{0} -> {1} (.1%)", input, Round(input, 0.001));
Console.WriteLine("{0} -> {1} (1%)", input, Round(input, 0.01));
Console.WriteLine("{0} -> {1} (10%)", input, Round(input, 0.1));
}
}
private double PrettyRound(double inp)
{
string d = inp.ToString();
d = d.Remove(0,d.IndexOf(',') + 1);
int decRound = 1;
bool onStartZeroes = true;
for (int c = 1; c < d.Length; c++ )
{
if (!onStartZeroes && d[c] == d[c - 1])
break;
else
decRound++;
if (d[c] != '0')
onStartZeroes = false;
}
inp = Math.Round(inp, decRound);
return inp;
}
Test:
double d1 = 0.13999; //no zeroes
double d2 = 0.0079996; //zeroes
double d3 = 0.00700956; //zeroes within decimal
Response.Write(d1 + "<br/>" + d2 + "<br/>" + d3 + "<br/><br/>");
d1 = PrettyRound(d1);
d2 = PrettyRound(d2);
d3 = PrettyRound(d3);
Response.Write(d1 + "<br/>" + d2 + "<br/>" + d3 +"<br/><br/>");
Prints:
0,13999
0,0079996
0,00700956
0,14
0,008
0,007
Rounds your numbers as you wrote in your example..
I can think of a solution though it isn't very efficient...
My assumption is that you can tell when a number is in the "best" human readable format when extra digits make no difference to how it is rounded.
eg in the example of 0,13999 rounding it to various numbers of decimal places gives:
0
0.1
0.14
0.14
0.14
0.13999
I'd suggest that you could loop through and detect that stable patch and cut off there.
This method seems to do this:
public double CustomRound(double d)
{
double currentRound = 0;
int stability = 0;
int roundLevel = 0;
while (stability < 3)
{
roundLevel++;
double current = Math.Round(d, roundLevel);
if (current == currentRound)
{
stability++;
}
else
{
stability = 1;
currentRound=current;
}
}
return Math.Round(d, roundLevel);
}
This code might be cleanable but it does the job and is a sufficient proof of concept. :)
I should emphasise that that initial assumption (that no change when rounding) is the criteria we are looking at which means that something like 0.3333333333 will not get rounded at all. With the examples given I'm unable to say if this is correct or not but I assume if this is a double issues that the problem is with the very slight variations from the "right" value and the value as a double.
Heres what I tried:
public decimal myRounding(decimal number)
{
double log10 = Math.Log10((double) number);
int precision = (int)(log10 >= 0 ? 0 : Math.Abs(log10)) + (number < 0.01m ? 1 : 2);
return Math.Round(number, precision);
}
test:
Console.WriteLine(myRounding(0.0000019999m)); //0.000002
Console.WriteLine(myRounding(0.0003019999m)); //0.0003
Console.WriteLine(myRounding(2.56777777m)); //2.57
Console.WriteLine(myRounding(0.13999m)); //0.14
Console.WriteLine(myRounding(0.0079996m)); //0.008
You can do it without converting to string. This is what I created fast:
private static double RoundDecimal(double number)
{
double temp2 = number;
int temp, counter = 0;
do
{
temp2 = 10 * temp2;
temp = (int)temp2;
counter++;
} while (temp < 1);
return Math.Round(number, counter < 2 ? 2 : counter);
}
or
private static double RoundDecimal(double number)
{
int counter = 0;
if (number > 0) {
counter = Math.Abs((int) Math.Log10(number)) + 1;
return Math.Round(arv, counter < 2 ? 2 : counter);
}
After giving it another thought I did the following and looks like it does what I want so far.
I iterate over the number of digits and compare Round( value, number ) and Round( value, number + 1 ). Once they are equal (not == of course - I compare the difference against a small number) then number is the number of digits I'm looking for.
Double.ToString() can take a string format as an argument. This will display as many characters as you require, rounding to the decimal place. E.G:
double Value = 1054.32179;
MessageBox.Show(Value.ToString("0.000"));
Will display "1054.322".
Source
Generic formats (i.e, pre-generated)
How to generate custom formats
You can use no of digits with Math.Round Function
Double doubleValue = 4.052102;
Math.Round(doubleValue, 2);
This will return 4.05 as your required answer.
This is tested code, can u explain me how i am wrong. So i need to change.

Split double into two int, one int before decimal point and one after

I need to split an double value, into two int value, one before the decimal point and one after. The int after the decimal point should have two digits.
Example:
10.50 = 10 and 50
10.45 = 10 and 45
10.5 = 10 and 50
This is how you could do it:
string s = inputValue.ToString("0.00", CultureInfo.InvariantCulture);
string[] parts = s.Split('.');
int i1 = int.Parse(parts[0]);
int i2 = int.Parse(parts[1]);
Manipulating strings can be slow. Try using the following:
double number;
long intPart = (long) number;
double fractionalPart = number - intPart;
What programming language you want to use to do this? Most of the language should have a Modulo operator. C++ example:
double num = 10.5;
int remainder = num % 1
"10.50".Split('.').Select(int.Parse);
/// <summary>
/// Get the integral and floating point portions of a Double
/// as separate integer values, where the floating point value is
/// raised to the specified power of ten, given by 'places'.
/// </summary>
public static void Split(Double value, Int32 places, out Int32 left, out Int32 right)
{
left = (Int32)Math.Truncate(value);
right = (Int32)((value - left) * Math.Pow(10, places));
}
public static void Split(Double value, out Int32 left, out Int32 right)
{
Split(value, 1, out left, out right);
}
Usage:
Int32 left, right;
Split(10.50, out left, out right);
// left == 10
// right == 5
Split(10.50, 2, out left, out right);
// left == 10
// right == 50
Split(10.50, 5, out left, out right);
// left == 10
// right == 50000
how about?
var n = 1004.522
var a = Math.Floor(n);
var b = n - a;
Another variation that doesn't involve string manipulation:
static void Main(string[] args)
{
decimal number = 10123.51m;
int whole = (int)number;
decimal precision = (number - whole) * 100;
Console.WriteLine(number);
Console.WriteLine(whole);
Console.WriteLine("{0} and {1}",whole,(int) precision);
Console.Read();
}
Make sure they're decimals or you get the usual strange float/double behaviour.
you can split with string and then convert into int ...
string s = input.ToString();
string[] parts = s.Split('.');
This function will take time in decimal and converts back into base 60 .
public string Time_In_Absolute(double time)
{
time = Math.Round(time, 2);
string[] timeparts = time.ToString().Split('.');
timeparts[1] = "." + timeparts[1];
double Minutes = double.Parse(timeparts[1]);
Minutes = Math.Round(Minutes, 2);
Minutes = Minutes * (double)60;
return string.Format("{0:00}:{1:00}",timeparts[0],Minutes);
//return Hours.ToString() + ":" + Math.Round(Minutes,0).ToString();
}
Try:
string s = "10.5";
string[] s1 = s.Split(new char[] { "." });
string first = s1[0];
string second = s1[1];
You can do it without going through strings. Example:
foreach (double x in new double[]{10.45, 10.50, 10.999, -10.323, -10.326, 10}){
int i = (int)Math.Truncate(x);
int f = (int)Math.Round(100*Math.Abs(x-i));
if (f==100){ f=0; i+=(x<0)?-1:1; }
Console.WriteLine("("+i+", "+f+")");
}
Output:
(10, 45)
(10, 50)
(11, 0)
(-10, 32)
(-10, 33)
(10, 0)
Won't work for a number like -0.123, though. Then again, I'm not sure how it would fit your representation.
I actually just had to answer this in the real world and while #David Samuel's answer did part of it here is the resulting code I used. As said before Strings are way too much overhead. I had to do this calculation across pixel values in a video and was still able to maintain 30fps on a moderate computer.
double number = 4140 / 640; //result is 6.46875 for example
int intPart = (int)number; //just convert to int, loose the dec.
int fractionalPart = (int)((position - intPart) * 1000); //rounding was not needed.
//this procedure will create two variables used to extract [iii*].[iii]* from iii*.iii*
This was used to solve x,y from pixel count in 640 X 480 video feed.
Console.Write("Enter the amount of money: ");
double value = double.Parse(Console.ReadLine());
int wholeDigits = (int) value;
double fractionalDigits = (value - wholeDigits) * 100;
fractionalDigits = (int) fractionalDigits;
Console.WriteLine(
"The number of the shekels is {0}, and the number of the agurot is {1}",
wholeDigits, fractionalDigits);
Using Linq. Just clarification of #Denis answer.
var parts = "10.50".Split('.').Select(int.Parse);
int i1 = parts.ElementAt(0);
int i2 = parts.ElementAt(1);

Categories