How do I round to the nearest 0.5? - c#

I have to display ratings and for that, I need increments as follows:
Input
Rounded
1.0
1
1.1
1
1.2
1
1.3
1.5
1.4
1.5
1.5
1.5
1.6
1.5
1.7
1.5
1.8
2.0
1.9
2.0
2.0
2.0
2.1
2.0
and so on...
Is there a simple way to compute the required values?

Multiply your rating by 2, then round using Math.Round(rating, MidpointRounding.AwayFromZero), then divide that value by 2.
Math.Round(value * 2, MidpointRounding.AwayFromZero) / 2

Multiply by 2, round, then divide by 2
if you want nearest quarter, multiply by 4, divide by 4, etc

Here are a couple of methods I wrote that will always round up or down to any value.
public static Double RoundUpToNearest(Double passednumber, Double roundto)
{
// 105.5 up to nearest 1 = 106
// 105.5 up to nearest 10 = 110
// 105.5 up to nearest 7 = 112
// 105.5 up to nearest 100 = 200
// 105.5 up to nearest 0.2 = 105.6
// 105.5 up to nearest 0.3 = 105.6
//if no rounto then just pass original number back
if (roundto == 0)
{
return passednumber;
}
else
{
return Math.Ceiling(passednumber / roundto) * roundto;
}
}
public static Double RoundDownToNearest(Double passednumber, Double roundto)
{
// 105.5 down to nearest 1 = 105
// 105.5 down to nearest 10 = 100
// 105.5 down to nearest 7 = 105
// 105.5 down to nearest 100 = 100
// 105.5 down to nearest 0.2 = 105.4
// 105.5 down to nearest 0.3 = 105.3
//if no rounto then just pass original number back
if (roundto == 0)
{
return passednumber;
}
else
{
return Math.Floor(passednumber / roundto) * roundto;
}
}

There are several options. If performance is a concern, test them to see which works fastest in a large loop.
double Adjust(double input)
{
double whole = Math.Truncate(input);
double remainder = input - whole;
if (remainder < 0.3)
{
remainder = 0;
}
else if (remainder < 0.8)
{
remainder = 0.5;
}
else
{
remainder = 1;
}
return whole + remainder;
}

decimal d = // your number..
decimal t = d - Math.Floor(d);
if(t >= 0.3d && t <= 0.7d)
{
return Math.Floor(d) + 0.5d;
}
else if(t>0.7d)
return Math.Ceil(d);
return Math.Floor(d);

Sounds like you need to round to the nearest 0.5. I see no version of round in the C# API that does this (one version takes a number of decimal digits to round to, which isn't the same thing).
Assuming you only have to deal with integer numbers of tenths, it's sufficient to calculate round (num * 2) / 2. If you're using arbitrarily precise decimals, it gets trickier. Let's hope you don't.

These lines of code snap a float dx to nearest snap:
if (snap <= 1f)
dx = Mathf.Floor(dx) + (Mathf.Round((dx - Mathf.Floor(dx)) * (1f / snap)) * snap);
else
dx = Mathf.Round(dx / snap) * snap;
So if snap is 0.5, value gets rounded to nearest 0.5 value (1.37 goes to 1.5), if it is 0.02, value is rounded to nearest 0.02 ((1.37 goes to 1.38)). If snap is 3, value is rounded to nearest 3 (7.4 goes to 6, 7.6 goes to 9) etc... I use it to quickly snap objects on scene in unity because unity default snapping doesn't seem to work well for me.

Public Function Round(ByVal text As TextBox) As Integer
Dim r As String = Nothing
If text.TextLength > 3 Then
Dim Last3 As String = (text.Text.Substring(text.Text.Length - 3))
If Last3.Substring(0, 1) = "." Then
Dim dimcalvalue As String = Last3.Substring(Last3.Length - 2)
If Val(dimcalvalue) >= 50 Then
text.Text = Val(text.Text) - Val(Last3)
text.Text = Val(text.Text) + 1
ElseIf Val(dimcalvalue) < 50 Then
text.Text = Val(text.Text) - Val(Last3)
End If
End If
End If
Return r
End Function

This answer is taken from Rosdi Kasim's comment in the answer that John Rasch provided.
John's answer works but does have an overflow possibility.
Here is my version of Rosdi's code:
I also put it in an extension to make it easy to use. The extension is not necessary and could be used as a function without issue.
<Extension>
Public Function ToHalf(value As Decimal) As Decimal
Dim integerPart = Decimal.Truncate(value)
Dim fractionPart = value - Decimal.Truncate(integerPart)
Dim roundedFractionPart = Math.Round(fractionPart * 2, MidpointRounding.AwayFromZero) / 2
Dim newValue = integerPart + roundedFractionPart
Return newValue
End Function
The usage would then be:
Dim newValue = CDec(1.26).ToHalf
This would return 1.5

I had difficulty with this problem as well.
I code mainly in Actionscript 3.0 which is base coding for the Adobe Flash Platform, but there are simularities in the Languages:
The solution I came up with is the following:
//Code for Rounding to the nearest 0.05
var r:Number = Math.random() * 10; // NUMBER - Input Your Number here
var n:int = r * 10; // INTEGER - Shift Decimal 2 places to right
var f:int = Math.round(r * 10 - n) * 5;// INTEGER - Test 1 or 0 then convert to 5
var d:Number = (n + (f / 10)) / 10; // NUMBER - Re-assemble the number
trace("ORG No: " + r);
trace("NEW No: " + d);
Thats pretty much it.
Note the use of 'Numbers' and 'Integers' and the way they are processed.
Good Luck!

Related

Rounding to the nearest number ending in 9

I have a website that calculates the price of bus tickets. Currently the price is rounded to the nearest 10, but now I want the calculated price to be rounded to the nearest number ending in 9.
EDIT: Added new examples answering question from the comments.
Examples:
770 to 774 should be rounded to 769
775 to 784 should be rounded to 779
785 to 790 should be rounded to 789
Does anybody have any tips on how I can solve my problem using c#?
Round to the nearest 10 and then subtract 1.
In c#, you can do it like this :
double val = 444.3;
double step1 = val/10; // 44.43
double step2 = Math.Round(step1, MidpointRounding.AwayFromZero); // 44
int step3 = (int)step2 * 10; // 440
int rndVal = step3 - 1; // rndVal == 439
or the shortest version :
double val = 444.3;
int rndVal = (int)(Math.Round(val/10, MidpointRounding.AwayFromZero)*10)-1;
Add 1, round to nearest 10 and then subtract 1.
The function below will do the job.
public static int RoundTo9(double value)
{
return (int)(value/10.0 + 0.5) * 10 - 1;
}
int number=65;
// Console.WriteLine(number);
int lastNumber=number%10;
//Console.WriteLine(lastNumber);
if(lastNumber<5)
{
number-=lastNumber;
number--;
Console.WriteLine(number);
}
else
{
var addNumber=10-lastNumber;
number+=addNumber;
number--;
Console.WriteLine(number);
}

Getting incorrect decimal places with percentage calculation [duplicate]

This question already has answers here:
C# is rounding down divisions by itself
(10 answers)
Closed 4 years ago.
I am performing calculations on 2 numbers like below :
No1 = 263
No2 = 260
Decimal places = 2
Expected output = 98.86
Code :
decimal output = 0;
int decimalPlaces = 2;
if (No1 > 0)
output = ((100 * Convert.ToDecimal(((No2 * 100) / No1))) / 100);
output = TruncateDecimal(output, decimalPlaces); // 98
public static decimal TruncateDecimal(decimal value, int precision)
{
decimal step = (decimal)Math.Pow(10, precision);
decimal tmp = Math.Truncate(step * value);
return tmp / step;
}
Above code renders output = 98
When i divide 263/260 in calculator i get 0.988593
decimalPlaces = 2 : Take 2 digits after decimal places
decimalPlaces = 2 : Round off will also take from this position after 2 decimal places i.e round off should take from 593 rendering 98.86
No1 = 117
No2 = 120
decimal places = 2
Expected Output = 97.50
Can anybody please me with this?
The problem is integer division. When you divide an integer by an integer, you will get an integer. You need to cast the values (at minimum one of them) to a decimal
output = Math.Round((100 * ((decimal)No2/(decimal)No1)),2);
try to change some parenthesis positions, from:
output = ((100 * Convert.ToDecimal(((No2 * 100) / No1))) / 100);
to
output = ((100 * ((Convert.ToDecimal(No2 * 100) / No1))) / 100);
In your code the division is calculated before decimal conversion, so you convert only integer result of the division.
Besides use Math.Round instead of Math.Truncate, in order to get your desired result.

rounded to the nearest 10's place in c#

I want to The numbers are being rounded to the nearest 10's place.
For example, a number like 17.3 is being rounded to 20.0. and want to be allow three significant digits. Meaning for round to the nearest tenth of a percent as the last step of the process.
Sample :
the number is 17.3 ,i want round to 20 ,
and this number is 13.3 , i want round to 10 ?
How can i do this ?
Chris Charabaruk gives you your desired answer here
To get to the core, here is his solution as an extension method:
public static class ExtensionMethods
{
public static int RoundOff (this int i)
{
return ((int)Math.Round(i / 10.0)) * 10;
}
}
int roundedNumber = 236.RoundOff(); // returns 240
int roundedNumber2 = 11.RoundOff(); // returns 10
//edit:
This method only works for int values. You'd have to edit this method to your liking.
f.e.:
public static class ExtensionMethods
{
public static double RoundOff (this double i)
{
return (Math.Round(i / 10.0)) * 10;
}
}
/edit2: As corak stated you should/could use
Math.Round(value / 10, MidpointRounding.AwayFromZero) * 10
Other answers are correct also, but here's how you'd do it without Math.Round:
((int)((17.3 + 5) / 10)) * 10 // = 20
((int)((13.3 + 5) / 10)) * 10 // = 10
((int)((15.0 + 5) / 10)) * 10 // = 20
Try this-
double d1 = 17.3;
int rounded1 = ((int)Math.Round(d/10.0)) * 10; // Output is 20
double d2 = 13.3;
int rounded2 = ((int)Math.Round(d/10.0)) * 10; // Output is 10
double Num = 16.6;
int intRoundNum = (Convert.ToInt32(Math.Round(Num / 10)) * 10);
Console.WriteLine(intRoundNum);
If you want to avoid casting or pulling in the math library you could also use the modulus operator and do something like the following:
int result = number - (number % 10);
if (number % 10 >= 5)
{
result += 10;
}
For your given numbers:
number
processing
result
13.3
13.3 - (3.3)
10
17.3
17.3 - (7.3) + 10
20

C# Formula to distribute numbers

I'm looking for a formula that can spread out numbers in a linear format based on a minimum number, max number and amount of numbers (or dots) between. The catch is, the closer you get to the max, the more numbers should be there.
An example (number will vary and will be about 100 times larger)
Min = 0
Max = 16
AmountOfNumbersToSpread = 6
0 1 2 3 4 5 6 7 8 9 A B C D E F
1 2 3 4 5 6
Thanks for the help in advance.
Based on the answer of Tal Pressman, you can write a distribution function like this:
IEnumerable<double> Spread(int min, int max, int count, Func<double, double> distribution)
{
double start = min;
double scale = max - min;
foreach (double offset in Redistribute(count, distribution))
yield return start + offset * scale;
}
IEnumerable<double> Redistribute(int count, Func<double, double> distribution)
{
double step = 1.0 / (count - 1);
for (int i = 0; i < count; i++)
yield return distribution(i * step);
}
You can use any kind of distribution function which maps [0;1] to [0;1] this way. Examples:
quadratic
Spread(0, 16, 6, x => 1-(1-x)*(1-x))
Output: 0 5.76 10.24 13.44 15.36 16
sine
Spread(0, 16, 6, x => Math.Sin(x * Math.PI / 2))
Output: 0 4.94427190999916 9.40456403667957 12.9442719099992 15.2169042607225 16
Basically, you should have something that looks like:
Generate a random number between 0 and 1.
Implement your desired distribution function (a 1:1 function from [0,1]->[0,1]).
Scale the result of the distribution function to match your desired range.
The exact function used for the second point is determined according to how exactly you want the numbers to be distributed, but according to your requirement, you'll want a function that has more values close to 1 than 0. For example, a sin or cos function.
Tried this on paper and it worked:
given MIN, MAX, AMOUNT:
Length = MAX - MIN
"mark" MIN and MAX
Length--, AMOUNT--
Current = MIN
While AMOUNT > 1
Space = Ceil(Length * Amount / (MAX - MIN))
Current += Space
"mark" Current
By "mark" I mean select that number, or whatever you need to do with it.
Close answer, not quite though, needs to work for larger numbers.
List<int> lstMin = new List<int>();
int Min = 1;
int Max = 1500;
int Length = Max - Min;
int Current = Min;
int ConnectedClient = 7;
double Space;
while(ConnectedClient > 0)
{
Space = Math.Ceiling((double)(Length * ConnectedClient / (Max - Min)));
Current += (int)Space;
ConnectedClient--;
Length--;
lstMin.Add(Current);
}

Excel RoundUp vs .NET Math.Round

in Excel, =ROUNDUP(474.872126666666, 2) -> 474.88
in .NET,
Math.Round(474.87212666666666666666666666667, 2, MidpointRounding.ToEven) // 474.87
Math.Round(474.87212666666666666666666666667, 2, MidpointRounding.AwayFromZero) // 474.87
My client want Excel rounding result, is there any way I can get 474.88 in .NET?
Thanks a lot
double ROUNDUP( double number, int digits )
{
return Math.Ceiling(number * Math.Pow(10, digits)) / Math.Pow(10, digits);
}
Math.Ceiling is what you're looking for.
Here's my try on a solution that behaves like Excel ROUNDUP function.
I tried to cover cases such as: negative decimal numbers, negative digits (yep Excel supports that), large decimal values
public static decimal RoundUp(decimal number, int digits)
{
if (digits > 0)
{
// numbers will have a format like +/-1.23, where the fractional part is optional if numbers are integral
// Excel RoundUp rounds negative numbers as if they were positive.
// To simulate this behavior we will use the absolute value of the number
// E.g. |1.23| = |-1.23| = 1.23
var absNumber = Math.Abs(number);
// Now take the integral part (E.g. for 1.23 is 1)
var absNumberIntegralPart = Decimal.Floor(absNumber);
// Now take the fractional part (E.g. for 1.23 is 0.23)
var fraction = (absNumber - absNumberIntegralPart);
// Multiply fractional part by the 10 ^ number of digits we're rounding to
// E.g. For 1.23 with rounded to 1 digit it will be 0.23 * 10^1 = 2.3
// Then we round that value UP using Decimal.Ceiling and we transform it back to a fractional part by dividing it by 10^number of digits
// E.g. Decimal.Ceiling(0.23 * 10) / 10 = Decimal.Ceiling(2.3) / 10 = 3 / 10 = 0.3
var tenPower = (decimal)Math.Pow(10, digits);
var fractionRoundedUp = Decimal.Ceiling(fraction * tenPower) / tenPower;
// Now we add up the absolute part with the rounded up fractional part and we put back the negative sign if needed
// E.g. 1 + 0.3 = 1.3
return Math.Sign(number) * (absNumberIntegralPart + fractionRoundedUp);
} else if (digits == 0)
{
return Math.Sign(number) * Decimal.Ceiling(Math.Abs(number));
} else if (digits < 0)
{
// negative digit rounding means that for RoundUp(149.12, -2) we will discard the fractional part, shift the decimal point on the left part 2 places before rounding up
// then replace all digits on the right of the decimal point with zeroes
// E.g. RoundUp(149.12, -2). Shift decimal point 2 places => 1.49. Now roundup(1.49) = 2 and we put 00 instead of 49 => 200
var absNumber = Math.Abs(number);
var absNumberIntegralPart = Decimal.Floor(absNumber);
var tenPower = (decimal)Math.Pow(10, -digits);
var absNumberIntegraPartRoundedUp = Decimal.Ceiling(absNumberIntegralPart / tenPower) * tenPower;
return Math.Sign(number)*absNumberIntegraPartRoundedUp;
}
return number;
}
[TestMethod]
public void Can_RoundUp_Correctly()
{
Assert.AreEqual(1.466m, MathExtensions.RoundUp(1.4655m, 3));
Assert.AreEqual(-1.466m, MathExtensions.RoundUp(-1.4655m, 3));
Assert.AreEqual(150m, MathExtensions.RoundUp(149.001m, 0));
Assert.AreEqual(-150m, MathExtensions.RoundUp(-149.001m, 0));
Assert.AreEqual(149.2m, MathExtensions.RoundUp(149.12m, 1));
Assert.AreEqual(149.12m, MathExtensions.RoundUp(149.12m, 2));
Assert.AreEqual(1232m, MathExtensions.RoundUp(1232, 2));
Assert.AreEqual(200m, MathExtensions.RoundUp(149.123m, -2));
Assert.AreEqual(-200m, MathExtensions.RoundUp(-149.123m, -2));
Assert.AreEqual(-20m, MathExtensions.RoundUp(-12.4655m, -1));
Assert.AreEqual(1.67m, MathExtensions.RoundUp(1.666666666666666666666666666m, 2));
Assert.AreEqual(1000000000000000000000000000m, MathExtensions.RoundUp(999999999999999999999999999m, -2));
Assert.AreEqual(10000000000000m, MathExtensions.RoundUp(9999999999999.999m, 2));
}
Here is the correct calculation for ROUNDUP and ROUNDDOWN:
private static object RoundDown(List<Expression> p)
{
var target = (decimal)p[0].Evaluate();
var digits = (decimal)p[1].Evaluate();
if (target < 0) return (Math.Ceiling((double)target * Math.Pow(10, (int)digits)) / Math.Pow(10, (int)digits));
return Math.Floor((double)target * Math.Pow(10, (int)digits)) / Math.Pow(10, (int)digits);
}
private static object RoundUp(List<Expression> p)
{
var target = (decimal)p[0].Evaluate();
var digits = (decimal)p[1].Evaluate();
if (target < 0) return (Math.Floor((double)target * Math.Pow(10, (int)digits)) / Math.Pow(10, (int)digits));
return Math.Ceiling((double)target * Math.Pow(10, (int)digits)) / Math.Pow(10, (int)digits);
}

Categories