Adding % sign without affecting my calculation - c#

I'm doing the following calculation: 0.697 * 100 in C# to get a percentage
in that same formula i'd like to add a % sign without it affecting the calculation simply as a plain text character.
There must be a way to include that sign without it considering 100% but instead 100 (plus just the sign%)

Adding the % character to a percentage is something you do when presenting it to the user. So, you add it when displaying the info:
float perc = 0.697 * 100;
System.out.println(String.Format("{0} %", perc));

Why not just return a string then?
public string Calculate(double x, double y) {
double result = x * y;
string returnResult = $"{result}%";
return returnResult;
}
public string Calculate(double x, double y) {
double result = x * y;
string returnResult = String.Format(result + "{0}", "%");
return returnResult;
}

Related

C# - Get X percent of Y dynamically

I've trying to calculate what is X% of Y, although I'm getting mixed results.
I've tried the following equations:
return (percent / i) * 100; // Gives 0 for 200.GetPercent(10)
return percent * 100 / i; // Gives 5 for 200.GetPercent(10)
For method:
public static int GetPercent(this int i, int percent)
{
return percent * 100 / i;
}
But none are giving me 20 back for 200.GetPercent(10)
I believe this is the correct equation: Y * X / 100
public static int GetPercent(this int i, int percent)
{
return (i * percent) / 100;
}
Percentages are better dealt with using a a floating point type, here is a version using double with another parameter to set precision
public static double GetPercent(this int i, double percent, int precision) =>
Math.Round(((i * percent) / 100), precision);
You can also define precision as an optional parameter, to give it a default value with int precision = n (n being an int of your choice)
public static double GetPercent(this int i, double percent, int precision = 2) =>
Math.Round(((i * percent) / 100), precision);
200.GetPercent(10, 4); //precision = 4
200.GetPercent(10); //precision defaults to = 2

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);

Get decimals of a double?

I have a function that adds a double to another double but I need to add only to the digits after the decimal point and the number of digits varies based on the size of the number.
public double Calculate(double x, double add)
{
string xstr;
if (x >= 10)
xstr = x.ToString("00.0000", NumberFormatInfo.InvariantInfo);
if (x >= 100)
xstr = x.ToString("000.000", NumberFormatInfo.InvariantInfo);
if (x < 10)
xstr = x.ToString("0.00000", NumberFormatInfo.InvariantInfo);
string decimals = xstr.Remove(0, xstr.IndexOf(".") + 1);
decimals = (Convert.ToDouble(decimals) + add).ToString();
xstr = xstr.Substring(0, xstr.IndexOf(".") + 1) + decimals;
x = Convert.ToDouble(xstr, NumberFormatInfo.InvariantInfo);
return x;
}
I'm wondering if there isn't a simpler way to do this without having to convert the number to string first and then adding to the decimal part of it.
As you can see the number to be added to should always be a 6 digit number where ever the decimal separator is.
If you take the remainder of the object divided by 1 you'll get the fractional portion of that number:
double remainder = someDouble % 1;
To write the whole method out, it's as simple as:
public double Calculate(double x, double add)
{
return Math.Floor(x) + (x + add) % 1;
}
(This is one of those times where you're glad that % computes the remainder, rather than the modulus. This will work as is for negative numbers as well.)
A little more elegant and much more faster:
public static double Calculate(double x, double add)
{
var pow = 5 - Math.Truncate(Math.Log10(x));
var multiplier = Math.Pow(10, pow);
var decimals = Math.Truncate((x % 1)* multiplier) + add;
x = Math.Truncate(x) + Math.Truncate(decimals) / multiplier;
return x;
}
So all you want to do is add the fractional part of each value? Why don't you just do this?
public double Calculate(double x, double y)
{
double fractional_x = x - Math.Floor(x);
double fractional_y = y - Math.Floor(y);
return fractional_x + fractional_y;
}
Here is yet another version:
public double Calculate(double x, double add)
{
return (x - (int)x) + (add - (int)add);
}

C# one number before floating point

I need to somehow get one number before floating point and value after that floating point. Example:
Before: 212.12345;
After: 2.12345
Any Ideas?
Assuming you have:
decimal x = 212.12345m;
you can use the modulo operator:
decimal result = x % 10;
Note that the number should be represented as a decimal if you care about the accurate value.
See also: Meaning of "%" operation in C# for the numeric type double
You can do like this:
public double GetFirst(double a)
{
double b = a / 10.0;
return (b - (int)b) * 10.0;
}
try this
double x = 1;
var y = x/10;
var z = (y % (Math.Floor(y))) * 10;
Try this code
string num = "15464612.12345";
string t = num.Split('.')[0];
num = t[t.Length-1].ToString() + "." + num.Split('.')[1];
my approach was to find the number 210, and substract it....
will work for any number as well as smaller then 10.
double f1 = 233.1234;
double f2 = f1 - (((int)f1 / 10) * 10);

Generate a random number in a Gaussian Range?

I want to use a random number generator that creates random numbers in a gaussian range where I can define the median by myself. I already asked a similar question here and now I'm using this code:
class RandomGaussian
{
private static Random random = new Random();
private static bool haveNextNextGaussian;
private static double nextNextGaussian;
public static double gaussianInRange(double from, double mean, double to)
{
if (!(from < mean && mean < to))
throw new ArgumentOutOfRangeException();
int p = Convert.ToInt32(random.NextDouble() * 100);
double retval;
if (p < (mean * Math.Abs(from - to)))
{
double interval1 = (NextGaussian() * (mean - from));
retval = from + (float)(interval1);
}
else
{
double interval2 = (NextGaussian() * (to - mean));
retval = mean + (float)(interval2);
}
while (retval < from || retval > to)
{
if (retval < from)
retval = (from - retval) + from;
if (retval > to)
retval = to - (retval - to);
}
return retval;
}
private static double NextGaussian()
{
if (haveNextNextGaussian)
{
haveNextNextGaussian = false;
return nextNextGaussian;
}
else
{
double v1, v2, s;
do
{
v1 = 2 * random.NextDouble() - 1;
v2 = 2 * random.NextDouble() - 1;
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = Math.Sqrt(-2 * Math.Log(s) / s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
}
Then to verify the results I plotted them with gaussianInRange(0, 0.5, 1) for n=100000000
As one can see the median is really at 0.5 but there isn't really a curve visible. So what I'm doing wrong?
EDIT
What i want is something like this where I can set the highest probability by myself by passing a value.
The simplest way to draw normal deviates conditional on them being in a particular range is with rejection sampling:
do {
retval = NextGaussian() * stdev + mean;
} while (retval < from || to < retval);
The same sort of thing is used when you draw coordinates (v1, v2) in a circle in your unconditional normal generator.
Simply folding in values outside the range doesn't produce the same distribution.
Also, if you have a good implementation of the error function and its inverse, you can calculate the values directly using an inverse CDF. The CDF of a normal distribution is
F(retval) = (1 + erf((retval-mean) / (stdev*sqrt(2)))) / 2
The CDF of a censored distribution is
C(retval) = (F(retval) - F(from)) / (F(to) - F(from)), from ≤ x < to
To draw a random number using a CDF, you draw v from a uniform distribution on [0, 1] and solve C(retval) = v. This gives
double v = random.NextDouble();
double t1 = erf((from - mean) / (stdev*sqrt(2)));
t2 = erf((to - mean) / (stdev*sqrt(2)));
double retval = mean + stdev * sqrt(2) * erf_inv(t1*(1-v) + t2*v);
You can precalculate t1 and t2 for specific parameters. The advantage of this approach is that there is no rejection sampling, so you only need a single NextDouble() per draw. If the [from, to] interval is small this will be faster.
However, it sounds like you might want the binomial distribution instead.
I have similar methods in my Graph generator (had to modify it a bit):
Returns a random floating-point number using a generator function with a specific range:
private double NextFunctional(Func<double, double> func, double from, double to, double height, out double x)
{
double halfWidth = (to - from) / 2;
double distance = halfWidth + from;
x = this.rand.NextDouble() * 2 - 1;// -1 .. 1
double y = func(x);
x = halfWidth * x + distance;
y *= height;
return y;
}
Gaussian function:
private double Gauss(double x)
{
// Graph should look better with double-x scale.
x *= 2;
double σ = 1 / Math.Sqrt(2 * Math.PI);
double variance = Math.Pow(σ, 2);
double exp = -0.5 * Math.Pow(x, 2) / variance;
double y = 1 / Math.Sqrt(2 * Math.PI * variance) * Math.Pow(Math.E, exp);
return y;
}
A method that generates a graph using the random numbers:
private void PlotGraph(Graphics g, Pen p, double from, double to, double height)
{
for (int i = 0; i < 1000; i++)
{
double x;
double y = this.NextFunctional(this.Gauss, from, to, height, out x);
this.DrawPoint(g, p, x, y);
}
}
I would rather used a cosine function - it is much faster and pretty close to the gaussian function for your needs:
double x;
double y = this.NextFunctional(a => Math.Cos(a * Math.PI), from, to, height, out x);
The out double x parameter in the NextFunctional() method is there so you can easily test it on your graphs (I use an iterator in my method).

Categories