% (mod) explanation - c#

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

Related

Get the amount of binary numbers that meet a criteria and are less than "x"

I am trying to get the count (just a number, not a list) of binary numbers that contain exactly 3 ones and that are less than 1000000000 ie: 10011, 100000011 and so on.
The code below works for integers, but how can I make it work with binary?
static void Main(string[] args)
{
int con = 0;
for (int i = 0; i < 1000000000; i++)
{
string test = i.ToString();
int count = test.Split('1').Length - 1;
if (count == 3)
{
con++;
}
}
Console.WriteLine(con);
}
And for your continued education, here's another way to solve the problem. We wish to know how many binary strings there are with exactly on on bits and off off bits.
There are some easy problems to solve in there. N(on, off) is equal to one if on and off are both zero, because the only solution is the empty string. And if either is zero then the answer is one, because the string that is all zeros or all ones is unique.
Let's start tabulating this in a table.
on
0 1 2 3 4 5
+---------------------
o 0| 1 1 1 1 1 1
f 1| 1
f 2| 1
3| 1
4| 1
5| 1
6| 1
Now what should go at (1, 1)? Well, the number of binary strings that have one on and one off bit is equal to the number of such strings that start with one, plus the number of such strings that start with zero. So we have:
N(1, 1) = N(1, 0) + N(0, 1) = 2
What about N(2, 1) ? Same deal:
N(2, 1) = N(1, 1) + N(2, 0) = 3
And we can see that similarly N(x, 1) = N(1, x) = x + 1. Fill in the array:
on
0 1 2 3 4 5
+---------------------
o 0| 1 1 1 1 1 1
f 1| 1 2 3 4 5 6
f 2| 1 3
3| 1 4
4| 1 5
5| 1 6
6| 1 7
in general for on, off not zero:
N(on, off) = N(on - 1, off) + N(on, off - 1)
which means that we can fill in this entire array by repeatedly applying this rule. Can you write a program which does so?
Once you do, you can simply read your answer out of the array at [6, 3].
Have you seen this pattern in this array before? It has a name. Hint: you probably have not seen it laid out as a square.
The simplest way to alter your code would be:
static void Main(string[] args)
{
int con = 0;
for (int i = 0; i < 512; i++)
{
string test = Convert.ToString(i, 2);
int count = test.Split('1').Length - 1;
if (count == 3)
{
con++;
}
}
Console.WriteLine(con);
}
This could be done as a pure mathematical equation though:
9! / (6!*3!) = 84
For your amusement and education, consider the following:
static IEnumerable<string> Combinations(int on, int off)
{
if (on == 0 && off == 0)
yield return "";
if (on > 0)
foreach(var s in Combinations(on - 1, off))
yield return "1" + s;
if (off > 0)
foreach(var s in Combinations(on, off - 1))
yield return "0" + s;
}
Study this implementation: it yields a sequence of binary strings with on bits on and off bits off. Do you see how it does so?
Plainly calling .Count() on this thing solves your problem, though such a solution is enormously less efficient than simply doing the math.
I present this for your study because a recursive enumerator such as this one is a powerful tool when investigating permutations and combinations.
A solution without resorting to string representations:
static int CountBits(int i)
{
var current = i;
var bits = 0;
while (current != 0)
{
if ((current & 1) == 1)
{
bits += 1;
}
current >>= 1;
}
return bits;
}
With this helper method, the count is easy:
var count = Enumerable.Range(0, 0b1000000000)
.Count(i => CountBits(i) == 3);
And the answer is 84.
Long code (grumpy style)
var con = 0;
for (var i = 0; i < 10000; i++)
{
var test = i.ToString();
if (test.Count(x => x == '1') == 3)
{
con++;
}
}
Console.WriteLine(con);
Shorter (more mature)
var con = Enumerable.Range(0, 10000)
.Select(x => $"{x:00000}")
.Count(x =>
x.Count(c => c == '1') == 3
);
Console.WriteLine(con);
PS: They both seem to have the same performance.

I need compute (9173501*9173502*9173504)%9173503 in C#;

I need compute (9173501 * 9173502 * 9173504) % 9173503 in C#; result = 2 but C# can't compute it.
If you have any idea please help me.
There is no need to use big integers.
Use this formula:
(x * y) % k = ((x % k) * (y % k)) % k
This way, you can apply the modulo to a product of two numbers, each of which will be < 9173503, so this product will fit in a long.
Note: the same holds true for addition:
(x + y) % k = ((x % k) + (y % k)) % k
And subtraction, with a slight change:
(x - y) % k = ((((x % k + k) % k) - ((y % k + k) % k)) % k + k) % k
It does not, however, hold for division:
(4 / 2) % 3 = 2
4 mod 3 = 1
2 mod 3 = 2
1 / 2 != 2
Convert your number to a BigInteger before you begin computations:
Console.WriteLine((new BigInteger(9173501)*9173502*9173504)%9173503);
// Output: 2
You can't directly compute it without BigInteger, but mathematically it's equivalent to:
((long)9173501 % 9173503) * (9173502 % 9173503) * (9173504 % 9173503) % 9173503
This is a math question, not a programming one.
As you see the numbers are really close to each other, so substituting n = 9173503 you will get: (n-2)(n-1)(n+1) % n.
Opening up the parenthesis you will get the following polynomial: n^3 - 2*n^2 - n + 2 and the remainder by n will be:
2 for every n > 2
0 for n = 1, 2
This means that not only (9173501 * 9173502 * 9173504) % 9173503 = 2, but also 13^127^61 * (13^127^61 + 1) * (13^127^61 + 3) % (13^127^61 + 2) is also 2, which is most probably can not be calculated with C# or other programming languages.

How can I generate a random BigInteger within a certain range?

Consider this method that works well:
public static bool mightBePrime(int N) {
BigInteger a = rGen.Next (1, N-1);
return modExp (a, N - 1, N) == 1;
}
Now, in order to fulfill a requirement of the class I'm taking, mightBePrime must accept a BigInteger N, but that means that I need a different way to generate my random BigInteger a.
My first idea was to do something like BigInteger a = (N-1) * rGen.NextDouble (), but a BigInteger can't be multiplied by a double.
How can I generate a random BigInteger between 1 and N-1, where N is a BigInteger?
Paul suggested in a comment that I generate a number using random bytes, then throw it away if it's too big. Here's what I came up with (Marcel's answer + Paul's advice):
public static BigInteger RandomIntegerBelow(BigInteger N) {
byte[] bytes = N.ToByteArray ();
BigInteger R;
do {
random.NextBytes (bytes);
bytes [bytes.Length - 1] &= (byte)0x7F; //force sign bit to positive
R = new BigInteger (bytes);
} while (R >= N);
return R;
}
http://amirshenouda.wordpress.com/2012/06/29/implementing-rsa-c/ helped a little too.
Use the Random-Class
public BigInteger getRandom(int length){
Random random = new Random();
byte[] data = new byte[length];
random.NextBytes(data);
return new BigInteger(data);
}
The naive implementation will fail on average 64 times before finding a valid BigInteger within the specified range.
On the worst case, my implementation will retry on average only 0.5 times (read as: 50% of the times it will find a result on the first try).
Also, unlike with modular arithmetic, my implementation maintains a uniform distribution.
Explanation
We must generate a random BigInteger between min and max.
If min > max, we swap min with max
To simplify the implementation we shift our range from [min, max] to [0, max-min], this way we won't have to deal with the sign bit
We count how many bytes max contains (bytes.Length)
From the most significant bit, we count how many bits are 0 (zeroBits)
We generate a random sequence of bytes.Length bytes
We know that for our sequence to be < max, at least zeroBits bits from the most significant bit must be 0, so we use a zeroBitMask to set them with a single bit-to-bit & operation over the most significant byte, this will save a lot of time by reducing the change of generating a number out of our range
We check if the number we generated is > max, and if so we try again
We unshift the range back from [0, max-min] to [min, max] by adding min to our result
And we have our number. 😊
Implementation
public static BigInteger RandomInRange(RandomNumberGenerator rng, BigInteger min, BigInteger max)
{
if (min > max)
{
var buff = min;
min = max;
max = buff;
}
// offset to set min = 0
BigInteger offset = -min;
min = 0;
max += offset;
var value = randomInRangeFromZeroToPositive(rng, max) - offset;
return value;
}
private static BigInteger randomInRangeFromZeroToPositive(RandomNumberGenerator rng, BigInteger max)
{
BigInteger value;
var bytes = max.ToByteArray();
// count how many bits of the most significant byte are 0
// NOTE: sign bit is always 0 because `max` must always be positive
byte zeroBitsMask = 0b00000000;
var mostSignificantByte = bytes[bytes.Length - 1];
// we try to set to 0 as many bits as there are in the most significant byte, starting from the left (most significant bits first)
// NOTE: `i` starts from 7 because the sign bit is always 0
for (var i = 7; i >= 0; i--)
{
// we keep iterating until we find the most significant non-0 bit
if ((mostSignificantByte & (0b1 << i)) != 0)
{
var zeroBits = 7 - i;
zeroBitsMask = (byte)(0b11111111 >> zeroBits);
break;
}
}
do
{
rng.GetBytes(bytes);
// set most significant bits to 0 (because `value > max` if any of these bits is 1)
bytes[bytes.Length - 1] &= zeroBitsMask;
value = new BigInteger(bytes);
// `value > max` 50% of the times, in which case the fastest way to keep the distribution uniform is to try again
} while (value > max);
return value;
}
Test
using (var rng = RandomNumberGenerator.Create())
{
BigInteger min = 0;
BigInteger max = 5;
var attempts = 10000000;
var count = new int[(int)max + 1];
var sw = Stopwatch.StartNew();
for (var i = 0; i < attempts; i++)
{
var v = BigIntegerUtils.RandomInRange(rng, min, max);
count[(int)v]++;
}
var time = sw.Elapsed;
Console.WriteLine("Generated {0} big integers from {1} to {2} in {3}", attempts, min, max, time);
Console.WriteLine("On average: {0} ms/integer or {1} integers/second", time.TotalMilliseconds / attempts, attempts / time.TotalSeconds);
for (var i = 0; i <= max; i++)
Console.WriteLine("{0} generated {1}% of the times ({2} times)", i, count[i] * 100d / attempts, count[i]);
}
Test output on my i7-6500U:
Generated 10000000 big integers from 0 to 5 in 00:00:09.5413677
On average: 0.00095413677 ms/integer or 1048067.77334449 integers/second
0 generated 16.66633% of the times (1666633 times)
1 generated 16.6717% of the times (1667170 times)
2 generated 16.66373% of the times (1666373 times)
3 generated 16.6666% of the times (1666660 times)
4 generated 16.68271% of the times (1668271 times)
5 generated 16.64893% of the times (1664893 times)
Another test output on my i7-6500U
Generated 10000000 big integers from 0 to 10^100 in 00:00:17.5036570
On average: 0.0017503657 ms/integer or 571309.184132207 integers/second
Here is a NextBigInteger extension method for the Random class. It is based on the excellent Fabio Iotti's implementation, modified for succinctness.
/// <summary>
/// Returns a random BigInteger that is within a specified range.
/// The lower bound is inclusive, and the upper bound is exclusive.
/// </summary>
public static BigInteger NextBigInteger(this Random random,
BigInteger minValue, BigInteger maxValue)
{
if (minValue > maxValue) throw new ArgumentException();
if (minValue == maxValue) return minValue;
BigInteger zeroBasedUpperBound = maxValue - 1 - minValue; // Inclusive
Debug.Assert(zeroBasedUpperBound.Sign >= 0);
byte[] bytes = zeroBasedUpperBound.ToByteArray();
Debug.Assert(bytes.Length > 0);
Debug.Assert((bytes[bytes.Length - 1] & 0b10000000) == 0);
// Search for the most significant non-zero bit
byte lastByteMask = 0b11111111;
for (byte mask = 0b10000000; mask > 0; mask >>= 1, lastByteMask >>= 1)
{
if ((bytes[bytes.Length - 1] & mask) == mask) break; // We found it
}
while (true)
{
random.NextBytes(bytes);
bytes[bytes.Length - 1] &= lastByteMask;
var result = new BigInteger(bytes);
Debug.Assert(result.Sign >= 0);
if (result <= zeroBasedUpperBound) return result + minValue;
}
}
The percentage of BigInteger instances that are discarded, in order to return a value within the desirable range, is 30% on average (best case 0%, worst case 50%).
The distribution of random numbers is uniform.
Usage example:
Random random = new();
BigInteger value = random.NextBigInteger(BigInteger.Zero, new BigInteger(1000));
Note: The structure of the bytes returned from the BigInteger.ToByteArray is well documented (in the Remarks section), so it should be fairly safe to assume that the BigInteger's byte[] representation is not going to change in future versions of the .NET platform. In case that happened, the above NextBigInteger implementation could fail in nasty ways, like entering an infinite loop or generating numbers within a wrong range. I've added some debugging assertions that should never fail with the current representation, but the coverage of checking for invalid conditions is by no means thorough.
Here's an alternate way to generate numbers within range without throwing away values and allowing BigIntegers for min and max.
public BigInteger RandomBigInteger(BigInteger min, BigInteger max)
{
Random rnd = new Random();
string numeratorString, denominatorString;
double fraction = rnd.NextDouble();
BigInteger inRange;
//Maintain all 17 digits of precision,
//but remove the leading zero and the decimal point;
numeratorString = fraction.ToString("G17").Remove(0, 2);
//Use the length instead of 17 in case the random
//fraction ends with one or more zeros
denominatorString = string.Format("1E{0}", numeratorString.Length);
inRange = (max - min) * BigInteger.Parse(numeratorString) /
BigInteger.Parse(denominatorString,
System.Globalization.NumberStyles.AllowExponent)
+ min;
return inRange;
}
For generality you may want to specify precision as well. This seems to work.
public BigInteger RandomBigIntegerInRange(BigInteger min, BigInteger max, int precision)
{
Random rnd = new Random();
string numeratorString, denominatorString;
double fraction = rnd.NextDouble();
BigInteger inRange;
numeratorString = GenerateNumeratorWithSpecifiedPrecision(precision);
denominatorString = string.Format("1E{0}", numeratorString.Length);
inRange = (max - min) * BigInteger.Parse(numeratorString) / BigInteger.Parse(denominatorString, System.Globalization.NumberStyles.AllowExponent) + min;
return inRange;
}
private string GenerateNumeratorWithSpecifiedPrecision(int precision)
{
Random rnd = new Random();
string answer = string.Empty;
while(answer.Length < precision)
{
answer += rnd.NextDouble().ToString("G17").Remove(0, 2);
}
if (answer.Length > precision) //Most likely
{
answer = answer.Substring(0, precision);
}
return answer;
}
For my use case, I did the following:
Random rnd = new Random();
BigInteger myVal = rnd.NextBigInteger(50,100); //returns a 50-99 bit BigInteger
The code:
/// <summary>
/// Returns a random BigInteger with a minimum bit count between <paramref name="minBitLength"/>(inclusive) and <paramref name="maxBitLength"/>(exclusive).
/// </summary>
/// <param name="minBitLength">The inclusive lower bit length of the random BigInteger returned.</param>
/// <param name="maxBitLength">The exclusive upper bit length of the random BigInteger returned. <paramref name="maxBitLength"/> must be greater than or equal to minValue.</param>
public static BigInteger NextBigInteger(this Random rnd, int minBitLength, int maxBitLength)
{
if (minBitLength < 0) throw new ArgumentOutOfRangeException();
int bits = rnd.Next(minBitLength, maxBitLength);
if (bits == 0) return BigInteger.Zero;
byte[] bytes = new byte[(bits + 7) / 8];
rnd.NextBytes(bytes);
// For the top byte, place a leading 1-bit then downshift to achieve desired length.
bytes[^1] = (byte)((0x80 | bytes[^1]) >> (7 - (bits - 1) % 8));
return new BigInteger(bytes, true);
}
Example Results:
____Example Lengths___ ___Example Results___
NextBigInteger(0,0) ==> 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0
NextBigInteger(0,1) ==> 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0
NextBigInteger(0,2) ==> 1 1 1 0 1 0 0 1 0 0 1 | 1 1 1 1 0 1 0
NextBigInteger(0,3) ==> 2 2 2 1 2 0 0 0 1 0 2 | 0 1 0 2 0 1 2
NextBigInteger(0,4) ==> 3 2 0 3 0 0 0 3 1 3 3 | 0 1 1 0 3 1 0
NextBigInteger(0,5) ==> 1 4 1 2 4 1 2 0 3 1 2 | 1 1 10 10 14 11 8
NextBigInteger(0,6) ==> 3 5 1 1 5 5 3 5 1 4 3 | 0 0 1 3 2 7 27
NextBigInteger(1,1) ==> 1 1 1 1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1
NextBigInteger(1,2) ==> 1 1 1 1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1
NextBigInteger(1,3) ==> 2 1 2 1 2 2 2 2 1 1 1 | 1 1 1 1 2 2 3
NextBigInteger(1,4) ==> 1 2 3 3 2 1 1 2 2 2 1 | 7 3 1 1 6 1 5
NextBigInteger(1,5) ==> 4 3 1 2 3 1 4 4 1 1 3 | 1 3 1 6 6 12 7
NextBigInteger(1,6) ==> 5 5 4 1 1 2 3 2 1 1 1 | 1 28 7 5 25 15 13
NextBigInteger(2,2) ==> 2 2 2 2 2 2 2 2 2 2 2 | 2 2 3 2 3 2 3
NextBigInteger(2,3) ==> 2 2 2 2 2 2 2 2 2 2 2 | 2 2 3 2 2 3 3
NextBigInteger(2,4) ==> 3 3 2 3 3 3 3 3 3 2 3 | 3 2 7 6 3 3 3
NextBigInteger(2,5) ==> 2 4 2 2 4 4 2 2 4 3 2 | 6 3 13 2 6 4 11
NextBigInteger(2,6) ==> 5 3 5 3 2 3 2 4 4 5 3 | 2 3 17 2 27 14 18
NextBigInteger(3,3) ==> 3 3 3 3 3 3 3 3 3 3 3 | 4 4 5 7 6 7 4
NextBigInteger(3,4) ==> 3 3 3 3 3 3 3 3 3 3 3 | 6 5 4 7 6 4 6
NextBigInteger(3,5) ==> 3 3 3 3 4 4 4 4 3 4 4 | 6 10 12 6 6 15 7
NextBigInteger(3,6) ==> 4 4 3 3 3 4 3 5 4 3 4 | 28 22 5 11 25 8 6
NextBigInteger(4,4) ==> 4 4 4 4 4 4 4 4 4 4 4 | 12 8 8 9 8 10 13
NextBigInteger(4,5) ==> 4 4 4 4 4 4 4 4 4 4 4 | 15 10 10 8 14 8 13
NextBigInteger(4,6) ==> 5 5 5 5 4 5 5 4 5 5 5 | 15 13 14 31 19 15 21
Some Random Stuff:
One issue with many large random number generators is they can produce output that are all similar in scale to the maxValue. Example: if we had something like RandomBigIntegerUsingValues(min: 100, max:999999999999999) then 99% of our results will be between 9999999999999 and 999999999999999. The odds of getting something under 1000000 are 1 in 1000000000.
Some range checking is implicitly handled by the Random.Next().
Matched .net libraries extension methods as best as possible so the name NextBigInteger() was used since it matches Random's built-in NextSingle(), NextDouble(), NextInt64() naming. And also .net's Random signature was was used: minBitLength(inclusive), maxBitLength(exclusive).
Releasing under the MIT License.
The following Range method will return an IEnumerable<BigInteger> within the range you specify.
A simple Extension method will return a random element within the IEnumerable.
public static IEnumerable<BigInteger> Range(BigInteger from, BigInteger to)
{
for(BigInteger i = from; i < to; i++) yield return i;
}
public static class Extensions
{
public static BigInteger RandomElement(this IEnumerable<BigInteger> enumerable, Random rand)
{
int index = rand.Next(0, enumerable.Count());
return enumerable.ElementAt(index);
}
}
usage:
Random rnd = new Random();
var big = Range(new BigInteger(10000000000000000), new BigInteger(10000000000000020)).RandomElement(rnd);
// returns random values and in this case it was 10000000000000003

Rounding integers to nearest multiple of 10 [duplicate]

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

How do you calculate if a number is a multiple of another number(well sort of)

pls, I HAVE A NUMBER say 9 and i want to find how to create a program to check if a number b is maybe 21(ie 9+12) or 33(ie 9 + 24) or 45(9 + 36) and so on. Can i get it in C# or SQL
With the clarification, it looks like you want to find whether there is an integer x for which (in math terms, not code)
b = 9 + 12x
is true; so you want to know whether b-9 is some multiple of 12; which is easy:
bool isMatch = ((b - 9) % 12) == 0;
and if you want to know which x:
int x = (b - 9) / 12;
It's not entirely clear from your question, but I think you're looking for the modulo operator. 21 % 12 = 9, 33 % 12 = 9, 45 % 12 = 9.
In C# and SQL this is just %, and it is used like an arithmetic operator (+, -, etc)
I think you've got three variables and than the solution will be like this:
var a = 9;
var b = 12;
var c = 21;
var isInRange = IsInRange(c, a, b);
private bool IsInRange(int input, int offset, int multiple){
return ((input - offset) % multiple) == 0;
}
Subtract your original number (in this case 9) from the number B, and then see if B % 12 is different from zero.

Categories

Resources