I need to round a double to nearest five. I can't find a way to do it with the Math.Round function. How can I do this?
What I want:
70 = 70
73.5 = 75
72 = 70
75.9 = 75
69 = 70
and so on..
Is there an easy way to do this?
Try:
Math.Round(value / 5.0) * 5;
This works and removes the need for an outer cast:
5 * (int)Math.Round(n / 5.0)
Here is a simple program that allows you to verify the code.
Be aware of the MidpointRounding parameter, without it you will get rounding to the closest even number, which in your case means difference of five (in the 72.5 example).
class Program
{
public static void RoundToFive()
{
Console.WriteLine(R(71));
Console.WriteLine(R(72.5)); //70 or 75? depends on midpoint rounding
Console.WriteLine(R(73.5));
Console.WriteLine(R(75));
}
public static double R(double x)
{
return Math.Round(x/5, MidpointRounding.AwayFromZero)*5;
}
static void Main(string[] args)
{
RoundToFive();
}
}
You can also write a generic function:
Option 1 - Method
public int Round(double i, int v)
{
return (int)(Math.Round(i / v) * v);
}
And use it like:
var value = Round(72, 5);
Option 2 - Extension method
public static double Round(this double value, int roundTo)
{
return (int)(Math.Round(value / roundTo) * roundTo);
}
And use it like:
var price = 72.0;
var newPrice = price.Round(5);
I did this this way:
int test = 5 * (value / 5);
for the next value (step 5) above, just add 5.
Related
Suppose I have number 87.6 of type double here I want to round it, so I have applied C# build in method of round to get the output something like this
double test2 = 87.6;
Console.WriteLine(Math.Round(test2, 0));
this will generate 88 which is fine. However, I wanted to be round back to 87 my logic would be on 0.8 and not on 0.5. So for instance if my input is 87.8 then I want to get 88 and if my input is 88.7 then I want to round it to 87.
I've got the answer from the comment section here is the logic for this
double test2 = 87.6;
test2 -= 0.3;
Console.WriteLine(Math.Round(test2, 0));
This 0.3 will make the difference
I think this would work:
public static class RoundingExtensions {
public static int RoundWithBreak(this valueToRound, double breakValue = .5) {
if (breakValue <= 0 || breakValue >= 1) { throw new Exception("Must be between 0 and 1") }
var difference = breakValue - .5;
var min = Math.Floor(breakValue);
var toReturn = Math.Round(breakValue - difference, 0);
return toReturn < min ? min : toReturn;
}
}
Consumed:
var test = 8.7;
var result = test.RoundWithBreak(.8);
This is the implementation from Microsoft for Sinh of a Complex
public static Complex Sinh(Complex value) /* Hyperbolic sin */
{
double a = value.m_real;
double b = value.m_imaginary;
return new Complex(Math.Sinh(a) * Math.Cos(b), Math.Cosh(a) * Math.Sin(b));
}
and the implementation for Cosh
public static Complex Cos(Complex value) {
double a = value.m_real;
double b = value.m_imaginary;
return new Complex(Math.Cos(a) * Math.Cosh(b), - (Math.Sin(a) * Math.Sinh(b)));
}
and finally the the implementation for Tanh
public static Complex Tanh(Complex value) /* Hyperbolic tan */
{
return (Sinh(value) / Cosh(value));
}
Source: https://referencesource.microsoft.com/System.Numerics/a.html#e62f37ac1d0c67da
I don't understand why Microsoft implented the Tanh method that way?
It will fail for very large values. E.g.:
tanh(709 + 0i) --> 1, ok
tanh(711 + 0i) --> NaN, failed should be 1
Any ideas how to improve the tanh method that?
For double the Math.Tanh methods works for large values.
The complex tanh method could be implemented like that:
public static Complex Tanh(Complex value)
{
double a = value.Real;
double b = value.Imaginary;
double tanh_a = Math.Tanh(a);
double tan_b = Math.Tan(b);
Complex num = new Complex(tanh_a, tan_b);
Complex den = new Complex(1, tanh_a * tan_b);
return num / den;
}
This will work as well for large values, see https://dotnetfiddle.net/xGWdQt.
Update
As well the complex tan method needs to be re-implemented that it works with larges values (imaginary part):
public static Complex Tan(Complex value)
{
double a = value.Real;
double b = value.Imaginary;
double tan_a = Math.Tan(a);
double tanh_b = Math.Tanh(b);
Complex num = new Complex(tan_a, tanh_b);
Complex den = new Complex(1, -tan_a * tanh_b);
return num / den;
}
See https://dotnetfiddle.net/dh6CSG.
Using the comment from Hans Passant another way to implement the tanh method would be:
public static Complex Tanh(Complex value)
{
if (Math.Abs(value.Real) > 20)
return new Complex(Math.Sign(value.Real), 0);
else
return Complex.Tanh(value);
}
See https://dotnetfiddle.net/QvUECX.
And the tan method:
public static Complex Tan(Complex value)
{
if (Math.Abs(value.Imaginary) > 20)
return new Complex(0, Math.Sign(value.Imaginary));
else
return Complex.Tan(value);
}
See https://dotnetfiddle.net/Xzclcu.
I want to pass a number and have the next whole number returned,
I've tried Math.Ceiling(3) , but it returns 3.
Desired output :
double val = 9.1 => 10
double val = 3 => 4
Thanks
There are two ways I would suggest doing this:
Using Math.Floor():
return Math.Floor(input + 1);
Using casting (to lose precision)
return (int)input + 1;
Fiddle here
Using just the floor or ceiling wont give you the next whole number in every case.
For eg:- If you input negative numbers. Better way is to create a function that does that.
public class Test{
public int NextWholeNumber(double n)
{
if(n < 0)
return 0;
else
return Convert.ToInt32(Math.Floor(n)+1);
}
// Main method
static public void Main()
{
Test o = new Test();
Console.WriteLine(o.NextWholeNumber(1.254));
}
}
Usually when you refer to whole number it is positive integers only. But if you require negative integers as well then you can try this, the code will return 3.0 => 4, -1.0 => 0, -1.1 => -1
double doubleValue = double.Parse(Console.ReadLine());
int wholeNumber = 0;
if ((doubleValue - Math.Floor(doubleValue) > 0))
{
wholeNumber = int.Parse(Math.Ceiling(doubleValue).ToString());
}
else
{
wholeNumber = int.Parse((doubleValue + 1).ToString());
}
Say I have the following functions:
public int Compute(int a, int b, int c)
{
return (a + b +c)/3;
}
public double Compute(double a, double b, double c)
{
return ((a + b + c) / 3.0) / 209;
}
I hope the difference is obvious. A double value needs to be divided by 209 (a constant value) while an integer is not.
What is the best way to combine these two functions in a single one using generics?
I'm not sure it makes sense here.
Generics are the approach to avoid writing the similar code for different object types.
But in your case, I don't see any similar code which could be generalized so keeping the functions different solves the task better.
Short Answer
You cannot turn it into one function.
Long Answer
The only common code you have is this:
return (a + b +c)/
You could use generics and do this at best (not possible with C#):
public static T Compute<T>(T a, T b, T c, T divisorSmall, int divisor)
{
return ((a + b + c) / divisorSmall) / divisor;
// Results in compiler error: Error CS0019 Operator '+' cannot be
// applied to operands of type 'T' and 'T'
}
and use it like this:
Compute(1, 2, 3, 3, 1); // For integers
Compute(1.0, 2.0, 6.0, 3.0, 209); // For doubles
But you cannot do that because you cannot restrict the type T to support arithmetic operation or restrict T to be numeric.
Also, even if it was possible, you do not gain much in this specific case because look how clumsy the usage looks in my hypothetical solution.
You shouldn't do it with generics, but you can test if a, b and c are ints and then select your operation:
private double Compute(double a, double b, double c)
{
/* check if a, b and c are integers int if true double if false */
return (a % 1 == 0 && b % 1 == 0 && c % 1 == 0) ? (a + b + c) / 3 : ((a + b + c) / 3.0) / 209;
}
[TestMethod()]
public void Int()
{
int a = 1;
int b = 2;
int c = 3;
int result = (int)Compute(a, b, c);
int expected = (1 + 2 + 3) / 3;
Assert.AreEqual(expected, result);
}
[TestMethod()]
public void Double()
{
double a = 1.1;
double b = 2.2;
double c = 3.3;
double result = Compute(a, b, c);
double expected = ((1.1 + 2.2 + 3.3) / 3.0) / 209;
Assert.AreEqual(expected, result);
}
Both tests are passing
I have an idea. I can create a method generic which receives an Delegate for each case int and double. This version fiddle works https://dotnetfiddle.net/Q15bYK
public static void Main()
{
Func<double,double,double,double> x = (d1,d2,d3) => {return ((d1 +d2 + d3)/ 3.0) / 209;};
Func<int,int,int,int> y = (i1,i2,i3) => {return (i1 + i2 + i3)/ 3;};
var rsDouble = Compute<double>(1.0,2.0,3.0,x);
Console.WriteLine(rsDouble);
var rsInt = Compute<int>(1,2,3,y);
Console.WriteLine(rsInt);
}
public static T Compute<T>(T a, T b, T c, Func<T,T,T,T> action)
{
return action(a,b,c);
}
But this seems my answer make complicated the situation and I agree with other answers, generics are used to write the similar code for different object types, not to write different code for each parameters.
OK the title is ugly but the problem is quite straightforward:
I have a WPF control where I want to display plot lines. My "viewport" has its limits, and these limits (for example, bottom and top value in object coordinates) are doubles.
So I would like to draw lines at every multiple of, say, 5. If my viewport goes from -8.3 to 22.8, I would get [-5, 0, 5, 10, 15, 20].
I would like to use LINQ, it seems the natural candidate, but cannot find a way...
I imagine something along these lines:
int nlines = (int)((upper_value - lower_value)/step);
var seq = Enumerable.Range((int)(Math.Ceiling(magic_number)), nlines).Select(what_else);
Given values are (double)lower_value, (double)upper_value and (int)step.
Enumerable.Range should do the trick:
Enumerable.Range(lower_value, upper_value - lower_value)
.Where(x => x % step == 0);
Try this code:
double lower_value = -8.3;
double upper_value = 22.8;
int step = 5;
int low = (int)lower_value / step;
int up = (int)upper_value / step;
var tt = Enumerable.Range(low, up - low + 1).Select(i => i * step);
EDIT
This code is intended for all negative values of the lower_value and for positive values which are divisible by the step. To make it work for all other positive values as well, the following correction should be applied:
if (lower_value > step * low)
low++;
The first problem is to determine the nearest factor of your step value from your starting point. Some simple arithmetic can deduce this value:
public static double RoundToMultiple(double value, double multiple)
{
return value - value % multiple;
}
To then create a sequence of all factors of a given value between a range an iterator block is well suited:
public static IEnumerable<double> FactorsInRange(
double start, double end, double factor)
{
var current = RoundToMultiple(start, factor);
while (start < end)
{
yield return start;
current = current + factor;
}
}
If you have the Generate method from MoreLinq, then you could write this without an explicit iterator block:
public static IEnumerable<double> FactorsInRange(
double start, double end, double factor)
{
return Generate(RoundToMultiple(start, factor),
current => current + factor)
.TakeWhile(current => current < end);
}
To avoid having to enumerate every number, you'll have to go outside of LINQ:
List<int> steps;
int currentStep = (lower_value / step) * step; //This takes advantage of integer division to "floor" the factor
steps.Add(currentStep);
while (currentStep < upper_value)
{
currentStep += step;
steps.Add(currentStep);
}
I made some adjustments to the code.
private List<int> getMultiples(double lower_value, double upper_value, int step) {
List<int> steps = new List<int>();
int currentStep = (int)(lower_value / step) * step; //This takes advantage of integer division to "floor" the factor
steps.Add(currentStep);
while (currentStep <= upper_value) {
steps.Add(currentStep);
currentStep += step;
}
return steps;
}