Rounding integers to nearest multiple of 10 [duplicate] - c#

This question already has answers here:
Returning the nearest multiple value of a number
(6 answers)
Closed 3 years ago.
I am trying to figure out how to round prices - both ways. For example:
Round down
43 becomes 40
143 becomes 140
1433 becomes 1430
Round up
43 becomes 50
143 becomes 150
1433 becomes 1440
I have the situation where I have a price range of say:
£143 - £193
of which I want to show as:
£140 - £200
as it looks a lot cleaner
Any ideas on how I can achieve this?

I would just create a couple methods;
int RoundUp(int toRound)
{
if (toRound % 10 == 0) return toRound;
return (10 - toRound % 10) + toRound;
}
int RoundDown(int toRound)
{
return toRound - toRound % 10;
}
Modulus gives us the remainder, in the case of rounding up 10 - r takes you to the nearest tenth, to round down you just subtract r. Pretty straight forward.

You don't need to use modulus (%) or floating point...
This works:
public static int RoundUp(int value)
{
return 10*((value + 9)/10);
}
public static int RoundDown(int value)
{
return 10*(value/10);
}

This code rounds to the nearest multiple of 10:
int RoundNum(int num)
{
int rem = num % 10;
return rem >= 5 ? (num - rem + 10) : (num - rem);
}
Very simple usage :
Console.WriteLine(RoundNum(143)); // prints 140
Console.WriteLine(RoundNum(193)); // prints 190

A general method to round a number to a multiple of another number, rounding away from zero.
For integer
int RoundNum(int num, int step)
{
if (num >= 0)
return ((num + (step / 2)) / step) * step;
else
return ((num - (step / 2)) / step) * step;
}
For float
float RoundNum(float num, float step)
{
if (num >= 0)
return floor((num + step / 2) / step) * step;
else
return ceil((num - step / 2) / step) * step;
}
I know some parts might seem counter-intuitive or not very optimized. I tried casting (num + step / 2) to an int, but this gave wrong results for negative floats ((int) -12.0000 = -11 and such). Anyways these are a few cases I tested:
any number rounded to step 1 should be itself
-3 rounded to step 2 = -4
-2 rounded to step 2 = -2
3 rounded to step 2 = 4
2 rounded to step 2 = 2
-2.3 rounded to step 0.2 = -2.4
-2.4 rounded to step 0.2 = -2.4
2.3 rounded to step 0.2 = 2.4
2.4 rounded to step 0.2 = 2.4

Divide the number by 10.
number = number / 10;
Math.Ceiling(number);//round up
Math.Round(number);//round down
Then multiply by 10.
number = number * 10;

public static int Round(int n)
{
// Smaller multiple
int a = (n / 10) * 10;
// Larger multiple
int b = a + 10;
// Return of closest of two
return (n - a > b - n) ? b : a;
}

Related

Time complexity for an analysis recursive algorithm

Any idea what the time complexity could be for this recursive algorithm please?
/* The function f(x) is unimodal over the range [min, max] and can be evaluated in Θ(1) time
* ε > 0 is the precision of the algorithm, typically ε is very small
* max > min
* n = (max - min)/ε, n > 0, where n is the problem size */
Algorithm(max, min){
if ((max - min) < ε){
return (max - min)/2 // return the answer
}
leftThird = (2 * min + max) / 3 // represents the point which is 1/3 of the way from min to max
rightThird = (min + 2 * max) / 3 // represents the point which is 2/3 of the way from min to max
if (f(leftThird) < f(rightThird))
{
return Algorithm(max,leftThird) // look for the answer in the interval between leftThird and max
}
else
{
return Algorithm(min, rightThird) // look for the answer in the interval between min and rightThird
}
}

Force Calculation to Round Up in C# [duplicate]

I want to round up double to int.
Eg,
double a=0.4, b=0.5;
I want to change them both to integer.
so that
int aa=0, bb=1;
aa is from a and bb is from b.
Any formula to do that?
Use Math.Ceiling to round up
Math.Ceiling(0.5); // 1
Use Math.Round to just round
Math.Round(0.5, MidpointRounding.AwayFromZero); // 1
And Math.Floor to round down
Math.Floor(0.5); // 0
Check out Math.Round. You can then cast the result to an int.
The .NET framework uses banker's rounding in Math.Round by default. You should use this overload:
Math.Round(0.5d, MidpointRounding.AwayFromZero) //1
Math.Round(0.4d, MidpointRounding.AwayFromZero) //0
Math.Round
Rounds a double-precision floating-point value to the nearest integral value.
Use a function in place of MidpointRounding.AwayFromZero:
myRound(1.11125,4)
Answer:- 1.1114
public static Double myRound(Double Value, int places = 1000)
{
Double myvalue = (Double)Value;
if (places == 1000)
{
if (myvalue - (int)myvalue == 0.5)
{
myvalue = myvalue + 0.1;
return (Double)Math.Round(myvalue);
}
return (Double)Math.Round(myvalue);
places = myvalue.ToString().Substring(myvalue.ToString().IndexOf(".") + 1).Length - 1;
} if ((myvalue * Math.Pow(10, places)) - (int)(myvalue * Math.Pow(10, places)) > 0.49)
{
myvalue = (myvalue * Math.Pow(10, places + 1)) + 1;
myvalue = (myvalue / Math.Pow(10, places + 1));
}
return (Double)Math.Round(myvalue, places);
}
Just some adjusting #BrunoLM's answer with more samples :
Math.Round(0.4); // =0
Math.Round(0.5); // =0
Math.Round(0.6); // =1
Math.Round(0.4, MidpointRounding.AwayFromZero); // = 0
Math.Round(0.5, MidpointRounding.AwayFromZero); // = 1
Math.Round(0.6, MidpointRounding.AwayFromZero); // = 1
Math.Round(0.4, MidpointRounding.ToEven); // = 0
Math.Round(0.5, MidpointRounding.ToEven); // = 0
Math.Round(0.6, MidpointRounding.ToEven); // = 1
Math.Round(0.5) returns zero due to floating point rounding errors, so you'll need to add a rounding error amount to the original value to ensure it doesn't round down, eg.
Console.WriteLine(Math.Round(0.5, 0).ToString()); // outputs 0 (!!)
Console.WriteLine(Math.Round(1.5, 0).ToString()); // outputs 2
Console.WriteLine(Math.Round(0.5 + 0.00000001, 0).ToString()); // outputs 1
Console.WriteLine(Math.Round(1.5 + 0.00000001, 0).ToString()); // outputs 2
Console.ReadKey();
Another option:
string strVal = "32.11"; // will return 33
// string strVal = "32.00" // returns 32
// string strVal = "32.98" // returns 33
string[] valStr = strVal.Split('.');
int32 leftSide = Convert.ToInt32(valStr[0]);
int32 rightSide = Convert.ToInt32(valStr[1]);
if (rightSide > 0)
leftSide = leftSide + 1;
return (leftSide);
It is also possible to round negative integers
// performing d = c * 3/4 where d can be pos or neg
d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
// explanation:
// 1.) multiply: c * a
// 2.) if c is negative: (c>0? subtract half of the dividend
// (b>>1) is bit shift right = (b/2)
// if c is positive: else add half of the dividend
// 3.) do the division
// on a C51/52 (8bit embedded) or similar like ATmega the below code may execute in approx 12cpu cycles (not tested)
Extended from a tip somewhere else in here. Sorry, missed from where.
/* Example test: integer rounding example including negative*/
#include <stdio.h>
#include <string.h>
int main () {
//rounding negative int
// doing something like d = c * 3/4
int a=3;
int b=4;
int c=-5;
int d;
int s=c;
int e=c+10;
for(int f=s; f<=e; f++) {
printf("%d\t",f);
double cd=f, ad=a, bd=b , dd;
// d = c * 3/4 with double
dd = cd * ad / bd;
printf("%.2f\t",dd);
printf("%.1f\t",dd);
printf("%.0f\t",dd);
// try again with typecast have used that a lot in Borland C++ 35 years ago....... maybe evolution has overtaken it ;) ***
// doing div before mul on purpose
dd =(double)c * ((double)a / (double)b);
printf("%.2f\t",dd);
c=f;
// d = c * 3/4 with integer rounding
d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
printf("%d\t",d);
puts("");
}
return 0;
}
/* test output
in 2f 1f 0f cast int
-5 -3.75 -3.8 -4 -3.75 -4
-4 -3.00 -3.0 -3 -3.75 -3
-3 -2.25 -2.2 -2 -3.00 -2
-2 -1.50 -1.5 -2 -2.25 -2
-1 -0.75 -0.8 -1 -1.50 -1
0 0.00 0.0 0 -0.75 0
1 0.75 0.8 1 0.00 1
2 1.50 1.5 2 0.75 2
3 2.25 2.2 2 1.50 2
4 3.00 3.0 3 2.25 3
5 3.75 3.8 4 3.00
// by the way evolution:
// Is there any decent small integer library out there for that by now?
It is simple. So follow this code.
decimal d = 10.5;
int roundNumber = (int)Math.Floor(d + 0.5);
Result is 11

Angle Normalization C#

I have an Angle class that has this constructor
public Angle(int deg, // Degrees, minutes, seconds
int min, // (Signs should agree
int sec) // for conventional notation.)
{
/* //Bug degree normalization
while (deg <= -180) deg += 360;
while (deg > Math.PI) deg -= 360;
//correction end */
double seconds = sec + 60 * (min + 60 * deg);
value = seconds * Math.PI / 648000.0;
normalize();
}
and I have these values for testing that constructor
int[] degrees = { 0, 180, -180, Int32.MinValue / 60, 120+180*200000};
int[] minutes = { 0, 0, 0, 0,56};
int[] seconds = { 0, 0, 0, 0,10};
Console.WriteLine("Testing constructor Angle(int deg, int min)");
for (int i = 0; i < degrees.Length; i++)
{
p = new Angle(degrees[i], minutes[i], seconds[i]);
Console.WriteLine("p = " + p);
}
/*Testing constructor Angle(int deg, int min)
p = 0°0'0"
p = 180°0'0"
p = 180°0'0"
p = 0°8'0" incorrect output
p = -73°11'50" incorrect output expected 120 56 10
*/
I do not understand why there is a bug here ? and why did they use divide Int32.MinValue by 60 and 120+180*200000 as this format ?
the comments in the constructor is a correction for the code
UPDATE: Added the code of normalize()
// For compatibility with the math libraries and other software
// range is (-pi,pi] not [0,2pi), enforced by the following function:
void normalize()
{
double twoPi = Math.PI + Math.PI;
while (value <= -Math.PI) value += twoPi;
while (value > Math.PI) value -= twoPi;
}
The problem is in this piece of code:
double seconds = sec + 60 * (min + 60 * deg);
Although you are storing seconds as a double, the conversion from int to double is taking place after sec + 60 * (min + 60 * deg) is computed as an int.
The compiler will not choose double arithmetics for you based on the type you decide to store the result in. The compiler will choose the best operator overload based on the types of the operands which in this case are all int and look for a valid implicit conversion (in this case int to double) afterwards; therefore it is choosing int arithmetics and the operation will overflow in the last two test cases:
Int32.MinValue / 60 * 60 * 60 = Int32.MinValue * 60 < Int32.MinValue which will overflow.
120 + 180 * 200000 * 60 * 60 > Int32.MaxValue which will also overflow.
Your expected results for these two cases are probably not considering this behavior.
In order to solve this issue, change your code to:
double seconds = sec + 60 * (min + 60f * deg);
Explicitly setting 60 to a double typed literal constant (60f) will force the compiler to resolve all operations to double arithmetics.
Also, it is worth pointing out that your constructor logic has some other issues:
You should be validating the input data; should it be valid to specify negative minutes or seconds? IMO that doesn't seem reasonable. Only deg should be allowed to have a negative value. You should check for this condition and act accordingly: throw an exception (preferable) or normalize sign of min and sec based on the sign of deg (ugly and potentially confusing).
Your seconds calculation doesn't seem to be correct for negative angles (again, this is tied to the previous issue and whatever sign convention you have decided to implement). Unless the convention is that negative angles must have negative deg, min and sec, the way you are computing seconds is wrong because you are always adding the minutes and seconds terms no matter the sign of deg.
UPDATE There is one more issue in your code that I missed until I had the chance to test it. Some of your test cases are failing because double doesn't have enough resolution. I think your code needs some major refactoring; normalize() should be called first. This way you will always be managing tightly bounded values that can not cause overflows or precision loss.
This is the way I would do it:
public Angle(int deg, int min, int sec)
{
//Omitting input values check.
double seconds = sec + 60 * (min + 60 * normalize(deg));
value = seconds * Math.PI / 648000f;
}
private int normalize(int deg)
{
int normalizedDeg = deg % 360;
if (normalizedDeg <= -180)
normalizedDeg += 360;
else if (normalizedDeg > 180)
normalizedDeg -= 360;
return normalizedDeg;
}
// For compatibility with the math libraries and other software
// range is (-pi,pi] not [0,2pi), enforced by the following function:
void normalize()
{double twoPi = Math.PI + Math.PI;
while (value <= -Math.PI) value += twoPi;
while (value > Math.PI) value -= twoPi;
}
This is the normalize function that I have
while loops is generally a bad idea. If you deal with small values it's okay, but imagine you have some angle like 1e+25, that'd be 1.59e+24 iterations or about 100 million years to compute if you have a decent CPU.
How it should be done instead:
static double NormalizeDegree360(double value)
{
var result = value % 360.0;
return result > 0 ? result : result + 360;
}
static double NormalizeDegree180(double value)
{
return (((value + 180) % 360) + 360) % 360 - 180;
}
static double TwoPI = 2*System.Math.PI;
static double NormalizeRadians2Pi(double value)
{
var result = value % TwoPI;
return result > 0 ? result : result + TwoPI;
}
static double NormalizeRadiansPi(double value)
{
return (((value + System.Math.PI) % TwoPI) + TwoPI) % TwoPI - System.Math.PI;
}
They're using the very large negative and positive numbers to make sure that the normalization caps angles to the range [-180, 180] degrees properly.

% (mod) explanation

Today I was writing a program in C#, and I used % to calculate some index... My program didn't work, so I debugged it and I realized that "%" is not working like in other program languages that I know.
For example:
In Python % returns values like this:
for x in xrange (-5, 6):
print x, "% 5 =", x % 5
-5 % 5 = 0
-4 % 5 = 1
-3 % 5 = 2
-2 % 5 = 3
-1 % 5 = 4
0 % 5 = 0
1 % 5 = 1
2 % 5 = 2
3 % 5 = 3
4 % 5 = 4
5 % 5 = 0
In C#:
for (int i = -5; i < 6; i++)
{
Console.WriteLine(i + " % 5 = " + i % 5);
}
-5 % 5 = 0
-4 % 5 = -4
-3 % 5 = -3
-2 % 5 = -2
-1 % 5 = -1
0 % 5 = 0
1 % 5 = 1
2 % 5 = 2
3 % 5 = 3
4 % 5 = 4
5 % 5 = 0
Did I do something wrong or is % not working like it should?
As explained in the comments, the different behaviour is by design. The different languages just ascribe different meanings to the % operator.
You ask:
How can I use modulus operator in C#?
You can define a modulus operator yourself that behaves the same way as the Python % operator:
int mod(int a, int n)
{
int result = a % n;
if ((result<0 && n>0) || (result>0 && n<0)) {
result += n;
}
return result;
}
Both answers are correct. Although personally I think the "always positive" one makes more sense.
You can define your own modulus function that only gives positive answers like this:
int mod(int a, int n) {
return ((a%n)+n) % n;
}
In modular arithmetic, one defines classes of numbers based on the modulo. In other words, in modulo m arithmetic, a number n is equivalent (read: the same) to n + m, n - m, n + 2m, n - 2m, etc.
One defines m "baskets" and every number falls in one (and only one) of them.
Example: one can say "It's 4:30 pm" or one can say "It's 16:30". Both forms mean exactly the same time, but are different representations of it.
Thus both, the Python and C# results are correct! The numbers are the same in the modulo 5 arithmetic you chose. It would also have been mathematically correct to return (5, 6, 7, 8, 9) for example. Just a bit odd.
As for the choice of representation (in other words, the choice on how to represent negative numbers), that is just a case of different design choices between the two languages.
However, that is not at all what the % operator actually does in C#. The % operator is not the canonical modulus operator; it is the remainder operator. The A % B operator actually answer the question "If I divided A by B using integer arithmetic, what would the remainder be?"
— What's the difference? Remainder vs Modulus by Eric Lippert
Quick snippet to get the canonical modulus:
return ((n % m) + m) % m;
Test implementation:
Mono/C#:
machine:~ user$ cat mod.cs
using System;
public class Program
{
public static void Main (string[] args)
{
Console.WriteLine(Mod(-2, 5));
Console.WriteLine(Mod(-5, 5));
Console.WriteLine(Mod(-2, -5));
}
public static int Mod (int n, int m)
{
return ((n % m) + m) % m;
}
}
machine:~ user$ mono mod.exe
3
0
-2
Python:
machine:~ user$ cat mod.py
print -2%5;
print -5%5;
print -2%-5;
machine:~ user$ python mod.py
3
0
-2

How to round up value C# to the nearest integer?

I want to round up double to int.
Eg,
double a=0.4, b=0.5;
I want to change them both to integer.
so that
int aa=0, bb=1;
aa is from a and bb is from b.
Any formula to do that?
Use Math.Ceiling to round up
Math.Ceiling(0.5); // 1
Use Math.Round to just round
Math.Round(0.5, MidpointRounding.AwayFromZero); // 1
And Math.Floor to round down
Math.Floor(0.5); // 0
Check out Math.Round. You can then cast the result to an int.
The .NET framework uses banker's rounding in Math.Round by default. You should use this overload:
Math.Round(0.5d, MidpointRounding.AwayFromZero) //1
Math.Round(0.4d, MidpointRounding.AwayFromZero) //0
Math.Round
Rounds a double-precision floating-point value to the nearest integral value.
Use a function in place of MidpointRounding.AwayFromZero:
myRound(1.11125,4)
Answer:- 1.1114
public static Double myRound(Double Value, int places = 1000)
{
Double myvalue = (Double)Value;
if (places == 1000)
{
if (myvalue - (int)myvalue == 0.5)
{
myvalue = myvalue + 0.1;
return (Double)Math.Round(myvalue);
}
return (Double)Math.Round(myvalue);
places = myvalue.ToString().Substring(myvalue.ToString().IndexOf(".") + 1).Length - 1;
} if ((myvalue * Math.Pow(10, places)) - (int)(myvalue * Math.Pow(10, places)) > 0.49)
{
myvalue = (myvalue * Math.Pow(10, places + 1)) + 1;
myvalue = (myvalue / Math.Pow(10, places + 1));
}
return (Double)Math.Round(myvalue, places);
}
Just some adjusting #BrunoLM's answer with more samples :
Math.Round(0.4); // =0
Math.Round(0.5); // =0
Math.Round(0.6); // =1
Math.Round(0.4, MidpointRounding.AwayFromZero); // = 0
Math.Round(0.5, MidpointRounding.AwayFromZero); // = 1
Math.Round(0.6, MidpointRounding.AwayFromZero); // = 1
Math.Round(0.4, MidpointRounding.ToEven); // = 0
Math.Round(0.5, MidpointRounding.ToEven); // = 0
Math.Round(0.6, MidpointRounding.ToEven); // = 1
Math.Round(0.5) returns zero due to floating point rounding errors, so you'll need to add a rounding error amount to the original value to ensure it doesn't round down, eg.
Console.WriteLine(Math.Round(0.5, 0).ToString()); // outputs 0 (!!)
Console.WriteLine(Math.Round(1.5, 0).ToString()); // outputs 2
Console.WriteLine(Math.Round(0.5 + 0.00000001, 0).ToString()); // outputs 1
Console.WriteLine(Math.Round(1.5 + 0.00000001, 0).ToString()); // outputs 2
Console.ReadKey();
Another option:
string strVal = "32.11"; // will return 33
// string strVal = "32.00" // returns 32
// string strVal = "32.98" // returns 33
string[] valStr = strVal.Split('.');
int32 leftSide = Convert.ToInt32(valStr[0]);
int32 rightSide = Convert.ToInt32(valStr[1]);
if (rightSide > 0)
leftSide = leftSide + 1;
return (leftSide);
It is also possible to round negative integers
// performing d = c * 3/4 where d can be pos or neg
d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
// explanation:
// 1.) multiply: c * a
// 2.) if c is negative: (c>0? subtract half of the dividend
// (b>>1) is bit shift right = (b/2)
// if c is positive: else add half of the dividend
// 3.) do the division
// on a C51/52 (8bit embedded) or similar like ATmega the below code may execute in approx 12cpu cycles (not tested)
Extended from a tip somewhere else in here. Sorry, missed from where.
/* Example test: integer rounding example including negative*/
#include <stdio.h>
#include <string.h>
int main () {
//rounding negative int
// doing something like d = c * 3/4
int a=3;
int b=4;
int c=-5;
int d;
int s=c;
int e=c+10;
for(int f=s; f<=e; f++) {
printf("%d\t",f);
double cd=f, ad=a, bd=b , dd;
// d = c * 3/4 with double
dd = cd * ad / bd;
printf("%.2f\t",dd);
printf("%.1f\t",dd);
printf("%.0f\t",dd);
// try again with typecast have used that a lot in Borland C++ 35 years ago....... maybe evolution has overtaken it ;) ***
// doing div before mul on purpose
dd =(double)c * ((double)a / (double)b);
printf("%.2f\t",dd);
c=f;
// d = c * 3/4 with integer rounding
d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
printf("%d\t",d);
puts("");
}
return 0;
}
/* test output
in 2f 1f 0f cast int
-5 -3.75 -3.8 -4 -3.75 -4
-4 -3.00 -3.0 -3 -3.75 -3
-3 -2.25 -2.2 -2 -3.00 -2
-2 -1.50 -1.5 -2 -2.25 -2
-1 -0.75 -0.8 -1 -1.50 -1
0 0.00 0.0 0 -0.75 0
1 0.75 0.8 1 0.00 1
2 1.50 1.5 2 0.75 2
3 2.25 2.2 2 1.50 2
4 3.00 3.0 3 2.25 3
5 3.75 3.8 4 3.00
// by the way evolution:
// Is there any decent small integer library out there for that by now?
It is simple. So follow this code.
decimal d = 10.5;
int roundNumber = (int)Math.Floor(d + 0.5);
Result is 11

Categories

Resources