Trying to calculate percentage amount but it always return a 0.
foreach (DataGridViewRow row in dataGridView1.Rows)
{
double igst_amt;
double amt = (Convert.ToDouble(row.Cells[dataGridView1.Columns[4].Index].Value)) * (Convert.ToDouble(row.Cells[dataGridView1.Columns[5].Index].Value));
row.Cells[dataGridView1.Columns[6].Index].Value = Convert.ToString(amt);
igst_amt = (igst/100)*(amt);
MessageBox.Show(Convert.ToString(igst_amt));
if (state == "o")
{
row.Cells[dataGridView1.Columns[9].Index].Value =Convert.ToString( (cgst / 100) *( amt));
row.Cells[dataGridView1.Columns[11].Index].Value =Convert.ToString( (sgst / 100) * (amt));
}
else if (state == "i")
{
row.Cells[dataGridView1.Columns[7].Index].Value = igst_amt;
}
double g_total = igst_amt + amt;
row.Cells[dataGridView1.Columns[13].Index].Value = Convert.ToString(g_total);
double t_g_total=0;
t_g_total+= g_total;
}
Let's break this down to the basic code required to reproduce the issue:
int igst = 10;
double amt = 42;
double igst_amt = (igst / 100) * (amt);
Console.WriteLine(igst_amt);
With this I get a result of 0.
However, if I write it like this:
double igst = 10;
double amt = 42;
double igst_amt = (igst / 100) * (amt);
Console.WriteLine(igst_amt);
Then I get 4.2.
I suspect that igst is actually an integer and you're performing integer arithmetic which will result in 0.
You should change igst to double or you can do this:
int igst = 10;
double amt = 42;
double igst_amt = igst * amt / 100;
Console.WriteLine(igst_amt);
A simple change to the calculation and it works.
Also, as a side note, you appear to be doing monetary calculations using double, but you should be using decimal as it is designed for money calculations.
Related
I tried to use RATE function in .NET CORE project.
There is a Visual Basic library I wanted to use but it does not work with .NET CORE.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.financial.rate?view=netframework-4.7.2
Are there any other ways to use it or should I calculate it explicitly? How? I can't find any explanation of this function.
According to #omajid comment I transform official VB code to C#.
This is all you need to use Rate method without dependency on Microsoft.VisualBasic.dll which is lacking this method in .NET CORE.
private double Rate(double NPer, double Pmt, double PV, double FV = 0, DueDate Due = DueDate.EndOfPeriod, double Guess = 0.1)
{
double dTemp;
double dRate0;
double dRate1;
double dY0;
double dY1;
int I;
// Check for error condition
if (NPer <= 0.0)
throw new ArgumentException("NPer must by greater than zero");
dRate0 = Guess;
dY0 = LEvalRate(dRate0, NPer, Pmt, PV, FV, Due);
if (dY0 > 0)
dRate1 = (dRate0 / 2);
else
dRate1 = (dRate0 * 2);
dY1 = LEvalRate(dRate1, NPer, Pmt, PV, FV, Due);
for (I = 0; I <= 39; I++)
{
if (dY1 == dY0)
{
if (dRate1 > dRate0)
dRate0 = dRate0 - cnL_IT_STEP;
else
dRate0 = dRate0 - cnL_IT_STEP * (-1);
dY0 = LEvalRate(dRate0, NPer, Pmt, PV, FV, Due);
if (dY1 == dY0)
throw new ArgumentException("Divide by zero");
}
dRate0 = dRate1 - (dRate1 - dRate0) * dY1 / (dY1 - dY0);
// Secant method of generating next approximation
dY0 = LEvalRate(dRate0, NPer, Pmt, PV, FV, Due);
if (Math.Abs(dY0) < cnL_IT_EPSILON)
return dRate0;
dTemp = dY0;
dY0 = dY1;
dY1 = dTemp;
dTemp = dRate0;
dRate0 = dRate1;
dRate1 = dTemp;
}
throw new ArgumentException("Can not calculate rate");
}
private double LEvalRate(double Rate, double NPer, double Pmt, double PV, double dFv, DueDate Due)
{
double dTemp1;
double dTemp2;
double dTemp3;
if (Rate == 0.0)
return (PV + Pmt * NPer + dFv);
else
{
dTemp3 = Rate + 1.0;
// WARSI Using the exponent operator for pow(..) in C code of LEvalRate. Still got
// to make sure that they (pow and ^) are same for all conditions
dTemp1 = Math.Pow(dTemp3, NPer);
if (Due != 0)
dTemp2 = 1 + Rate;
else
dTemp2 = 1.0;
return (PV * dTemp1 + Pmt * dTemp2 * (dTemp1 - 1) / Rate + dFv);
}
}
private const double cnL_IT_STEP = 0.00001;
private const double cnL_IT_EPSILON = 0.0000001;
enum DueDate
{
EndOfPeriod = 0,
BegOfPeriod = 1
}
I have the following function that typically need to return a value. I calculate the value in a calculator app and I get values just fine. But in the program below the value variable value is always 0. I have tried using long, double, float but nothing works. Please help.
public string CalculateElapsedPercent(DateTime endTime, DateTime startTime)
{
string result = string.Empty;
DateTime currentTime = DateTime.Now;
if (currentTime > endTime)
{
result = " (100 %)";
return result;
}
long nr = (currentTime - startTime).Ticks;
long dr = (endTime - startTime).Ticks;
double value = (nr / dr) * 100.0;
result = " (" + value.ToString() + " %)";
return result;
}
Since both nr and dr are long, the result of (nr / dr) is long, and since dr is greater that nr, the result is equal to 0.
In order to fix that, you can convert it to double during calculation:
double value = ((double)nr / (double)dr) * 100.0;
Or you can define nr and dr as doubles:
double nr = (currentTime - startTime).Ticks;
double dr = (endTime - startTime).Ticks;
double value = (nr / dr) * 100.0;
The behavior in your original code sample is called integer division. See Division operator article in C# Specification or Why integer division in c# returns an integer but not a float? stackoverflow question for more info
nr and dr are integers, which means the nr/dr is an integer division, and since dr will always be larger than nr, you get zero.
Convert them to a double before dividing:
double nr = Convert.ToDouble((currentTime - startTime).Ticks);
double dr = Convert.ToDouble((endTime - startTime).Ticks);
double value = (nr / dr) * 100.0;
You are performing integer division (nr / dr), which means you lose all the decimal values.
You instead want to perform floating point division. You can do that by casting nr or dr to double. Or, in your case, you could just move up the multiplication by 100.0 a little (multiplying by 100.0, forces nr to be cast to a double, which then means that dr will also be automatically cast to double for the division):
double value = nr * 100.0 / dr;
nr and dr are both long which is essentially integers. If you go with a (nr / dr) and dr is larger than nr, you would end up with zero as a result of the division. Just cast nr and dr to double and your problems would be solved. :)
public string CalculateElapsedPercent(DateTime endTime, DateTime startTime)
{
string result = string.Empty;
DateTime currentTime = DateTime.Now;
if (currentTime > endTime)
{
result = " (100 %)";
return result;
}
long nr = (currentTime - startTime).Ticks;
long dr = (endTime - startTime).Ticks;
double value = ((double)nr / (double)dr) * 100.0;
result = " (" + value.ToString() + " %)";
return result;
}
Others have already explained the issue, but I would also like to suggest a little improvement to your method. For example, like this:
public static string CalculateElapsedPercent(DateTime endTime, DateTime startTime)
{
double ratio;
DateTime currentTime = DateTime.Now;
if (currentTime > endTime)
{
ratio = 1;
}
else
{
var elapsed = currentTime - startTime;
var total = endTime - startTime;
ratio = elapsed.TotalMinutes / total.TotalMinutes;
}
return string.Format(" ({0:P2})", ratio);
}
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);
I need get fractional part of double like int and only two numbers. My code
(int)Math.Floor(val * 100 - (int)val * 100)
but this can (int)val * 100 may be out of range of int or long. Ok.
If i try
(int)Math.Floor((val - (int)val) * 100)
Return value may be incorrect. For example:
double val = 56.9;
int retVal = (int)Math.Floor((val - (int)val) * 100);
// retVal = 89, because (val - (int)val) return 0.899999999675
How correct get fractional part of double like int?
Try this extensions method:
public static int GetFrac2Digits(this double d)
{
var str = d.ToString("0.00", CultureInfo.InvariantCulture);
return int.Parse(str.Substring(str.IndexOf('.') + 1));
}
try this
double val = 56.9;
double result=0;
int retVal = (int)Math.Floor((val - (int)val) * 100);
// retVal = 89, because (val - (int)val) return 0.899999999675
int FrctPart=result.ToString().Split('.')[1]
Like this maybe?
decimal d = (decimal)val;
int retVal = Math.Floor((d - Math.Floor(d)) * 100);
// 59.9 --> 90
// 123.456 --> 45
You could also use Math.Truncate instead of casting to int:
double val = 56.9;
int retVal = (int)Math.Round((val-Math.Truncate(val)) * 100);
// retVal is now 90
The result of all of the division equations in the below for loop is 0. How can I get it to give me a decimal e.g.:
297 / 315 = 0.30793650793650793650793650793651
Code:
using System;
namespace TestDivide
{
class Program
{
static void Main(string[] args)
{
for (int i = 0; i <= 100; i++)
{
decimal result = i / 100;
long result2 = i / 100;
double result3 = i / 100;
float result4 = i / 100;
Console.WriteLine("{0}/{1}={2} ({3},{4},{5}, {6})", i, 100, i / 100, result, result2, result3, result4);
}
Console.ReadLine();
}
}
}
Answer:
Thanks Jon and everyone, this is what I wanted to do:
using System;
namespace TestDivide
{
class Program
{
static void Main(string[] args)
{
int maximum = 300;
for (int i = 0; i <= maximum; i++)
{
float percentage = (i / (float)maximum) * 100f;
Console.WriteLine("on #{0}, {1:#}% finished.", i, percentage);
}
Console.ReadLine();
}
}
}
You're using int/int, which does everything in integer arithmetic even if you're assigning to a decimal/double/float variable.
Force one of the operands to be of the type you want to use for the arithmetic.
for (int i = 0; i <= 100; i++)
{
decimal result = i / 100m;
long result2 = i / 100;
double result3 = i / 100d;
float result4 = i / 100f;
Console.WriteLine("{0}/{1}={2} ({3},{4},{5}, {6})",
i, 100, i / 100d, result, result2, result3, result4);
}
Results:
0/100=0 (0,0,0, 0)
1/100=0.01 (0.01,0,0.01, 0.01)
2/100=0.02 (0.02,0,0.02, 0.02)
3/100=0.03 (0.03,0,0.03, 0.03)
4/100=0.04 (0.04,0,0.04, 0.04)
5/100=0.05 (0.05,0,0.05, 0.05)
(etc)
Note that that isn't showing the exact value represented by the float or the double - you can't represent 0.01 exactly as a float or double, for example. The string formatting is effectively rounding the result. See my article on .NET floating binary point for more information as well as a class which will let you see the exact value of a double.
I haven't bothered using 100L for result2 because the result would always be the same.
Try
i / 100.0
because i is an int: i / 100 performs integer division, then the result, that is always 0, is casted to the target type. You need to specify at least one non-int literal in your expression:
i / 100.0
Because i is an integer and 100 is an integer...so you have an integer division
Try (decimal)i / 100.0 instead
No matter where you store it, an integer divided by an integer will always be an integer.
You need to force a floating point operation "double / double" instead of an "int / int"
double result = (double)297 / (double)315 ;
this is integer division whatever the type of variable you storing in,
so int / int = int
double result3 = ((double)i) / 100;
Because i is a int value and you divide by an integer so the result is an integer ! and so you need to divide by 100.0 to have an implicit cast in float or specify 100f or 100d
In my case I had only vars and no int
float div = (var1 - var2) / float.Parse(var1.ToString());