I'm trying to mod an integer to get an array position so that it will loop round. Doing i %
arrayLength works fine for positive numbers but for negative numbers it all goes wrong.
4 % 3 == 1
3 % 3 == 0
2 % 3 == 2
1 % 3 == 1
0 % 3 == 0
-1 % 3 == -1
-2 % 3 == -2
-3 % 3 == 0
-4 % 3 == -1
so i need an implementation of
int GetArrayIndex(int i, int arrayLength)
such that
GetArrayIndex( 4, 3) == 1
GetArrayIndex( 3, 3) == 0
GetArrayIndex( 2, 3) == 2
GetArrayIndex( 1, 3) == 1
GetArrayIndex( 0, 3) == 0
GetArrayIndex(-1, 3) == 2
GetArrayIndex(-2, 3) == 1
GetArrayIndex(-3, 3) == 0
GetArrayIndex(-4, 3) == 2
I've done this before but for some reason it's melting my brain today :(
I always use my own mod function, defined as
int mod(int x, int m) {
return (x%m + m)%m;
}
Of course, if you're bothered about having two calls to the modulus operation, you could write it as
int mod(int x, int m) {
int r = x%m;
return r<0 ? r+m : r;
}
or variants thereof.
The reason it works is that "x%m" is always in the range [-m+1, m-1]. So if at all it is negative, adding m to it will put it in the positive range without changing its value modulo m.
Please note that C# and C++'s % operator is actually NOT a modulo, it's remainder. The formula for modulo that you want, in your case, is:
float nfmod(float a,float b)
{
return a - b * floor(a / b);
}
You have to recode this in C# (or C++) but this is the way you get modulo and not a remainder.
Single-line implementation using % only once:
int mod(int k, int n) { return ((k %= n) < 0) ? k+n : k; }
Comparing top two answers
(x%m + m)%m;
and
int r = x%m;
return r<0 ? r+m : r;
Nobody actually mentioned the fact that the first one may throw an OverflowException while the second one won't. Even worse, with default unchecked context, the first answer may return the wrong answer (see mod(int.MaxValue - 1, int.MaxValue) for example). So the second answer not only seems to be faster, but also more correct.
ShreevatsaR's answer won't work for all cases, even if you add "if(m<0) m=-m;", if you account for negative dividends/divisors.
For example, -12 mod -10 will be 8, and it should be -2.
The following implementation will work for both positive and negative dividends / divisors and complies with other implementations (namely, Java, Python, Ruby, Scala, Scheme, Javascript and Google's Calculator):
internal static class IntExtensions
{
internal static int Mod(this int a, int n)
{
if (n == 0)
throw new ArgumentOutOfRangeException("n", "(a mod 0) is undefined.");
//puts a in the [-n+1, n-1] range using the remainder operator
int remainder = a%n;
//if the remainder is less than zero, add n to put it in the [0, n-1] range if n is positive
//if the remainder is greater than zero, add n to put it in the [n-1, 0] range if n is negative
if ((n > 0 && remainder < 0) ||
(n < 0 && remainder > 0))
return remainder + n;
return remainder;
}
}
Test suite using xUnit:
[Theory]
[PropertyData("GetTestData")]
public void Mod_ReturnsCorrectModulo(int dividend, int divisor, int expectedMod)
{
Assert.Equal(expectedMod, dividend.Mod(divisor));
}
[Fact]
public void Mod_ThrowsException_IfDivisorIsZero()
{
Assert.Throws<ArgumentOutOfRangeException>(() => 1.Mod(0));
}
public static IEnumerable<object[]> GetTestData
{
get
{
yield return new object[] {1, 1, 0};
yield return new object[] {0, 1, 0};
yield return new object[] {2, 10, 2};
yield return new object[] {12, 10, 2};
yield return new object[] {22, 10, 2};
yield return new object[] {-2, 10, 8};
yield return new object[] {-12, 10, 8};
yield return new object[] {-22, 10, 8};
yield return new object[] { 2, -10, -8 };
yield return new object[] { 12, -10, -8 };
yield return new object[] { 22, -10, -8 };
yield return new object[] { -2, -10, -2 };
yield return new object[] { -12, -10, -2 };
yield return new object[] { -22, -10, -2 };
}
}
I like the trick presented by Peter N Lewis on this thread: "If n has a limited range, then you can get the result you want simply by adding a known constant multiple of [the divisor] that is greater that the absolute value of the minimum."
So if I have a value d that is in degrees and I want to take
d % 180f
and I want to avoid the problems if d is negative, then instead I just do this:
(d + 720f) % 180f
This assumes that although d may be negative, it is known that it will never be more negative than -720.
Just add your modulus (arrayLength) to the negative result of % and you'll be fine.
You're expecting a behaviour that is contrary to the documented behaviour of the % operator in c# - possibly because you're expecting it to work in a way that it works in another language you are more used to. The documentation on c# states (emphasis mine):
For the operands of integer types, the result of a % b is the value produced by a - (a / b) * b. The sign of the non-zero remainder is the same as that of the left-hand operand
The value you want can be calculated with one extra step:
int GetArrayIndex(int i, int arrayLength){
int mod = i % arrayLength;
return (mod>=0) : mod ? mod + arrayLength;
}
For the more performance aware devs
uint wrap(int k, int n) ((uint)k)%n
A small performance comparison
Modulo: 00:00:07.2661827 ((n%x)+x)%x)
Cast: 00:00:03.2202334 ((uint)k)%n
If: 00:00:13.5378989 ((k %= n) < 0) ? k+n : k
As for performance cost of cast to uint have a look here
Adding some understanding.
By Euclidean definition the mod result must be always positive.
Ex:
int n = 5;
int x = -3;
int mod(int n, int x)
{
return ((n%x)+x)%x;
}
Output:
-1
All of the answers here work great if your divisor is positive, but it's not quite complete. Here is my implementation which always returns on a range of [0, b), such that the sign of the output is the same as the sign of the divisor, allowing for negative divisors as the endpoint for the output range.
PosMod(5, 3) returns 2
PosMod(-5, 3) returns 1
PosMod(5, -3) returns -1
PosMod(-5, -3) returns -2
/// <summary>
/// Performs a canonical Modulus operation, where the output is on the range [0, b).
/// </summary>
public static real_t PosMod(real_t a, real_t b)
{
real_t c = a % b;
if ((c < 0 && b > 0) || (c > 0 && b < 0))
{
c += b;
}
return c;
}
(where real_t can be any number type)
A single line implementation of dcastro's answer (the most compliant with other languages):
int Mod(int a, int n)
{
return (((a %= n) < 0) && n > 0) || (a > 0 && n < 0) ? a + n : a;
}
If you'd like to keep the use of % operator (you can't overload native operators in C#):
public class IntM
{
private int _value;
private IntM(int value)
{
_value = value;
}
private static int Mod(int a, int n)
{
return (((a %= n) < 0) && n > 0) || (a > 0 && n < 0) ? a + n : a;
}
public static implicit operator int(IntM i) => i._value;
public static implicit operator IntM(int i) => new IntM(i);
public static int operator %(IntM a, int n) => Mod(a, n);
public static int operator %(int a, IntM n) => Mod(a, n);
}
Use case, both works:
int r = (IntM)a % n;
// Or
int r = a % n(IntM);
Here's my one liner for positive integers, based on this answer:
usage:
(-7).Mod(3); // returns 2
implementation:
static int Mod(this int a, int n) => (((a %= n) < 0) ? n : 0) + a;
There are many implementations of the mod function, and I think it's worth it to list all of them --- at least according to Wikipedia, I'm sure there are more.
// Important to be able to use `MathF`.
using System;
public static class MathFUtils {
public static class Mod {
public static float Trunc(float a, float b) =>
a - b * ((int)(a / b));
public static float Round(float a, float b) =>
a - b * MathF.Round(a / b);
public static float Floor(float a, float b) =>
a - b * MathF.Floor(a / b);
public static float Ceil(float a, float b) =>
a - b * MathF.Ceiling(a / b);
public static float Euclidean(float a, float b) =>
a - MathF.Abs(b) * MathF.Floor(a / MathF.Abs(b));
}
}
According to the Wikipedia (as well as my experience) stick to Euclidean. It is the most useful in terms of mathematical and probabilistic properties. If you ever need Trunc, then I believe % does just that.
Also, for those of you who might be confused as to what each of them do, and how, I highly recommend reading the Wikipedia article (even if it's hard) and looking at the images of each representation.
Of course these are not necessarily the most performant, but they do work. If you are concerned about performance, I recommend finding a local C# god, or asking one as they pass through our mortal plane.
ShreevatsaR's second answer:
int mod(int x, int m) {
int r = x % m;
return r < 0 ? r + m : r;
}
can be written using the var pattern and switch expressions in newer versions of C# as a one-liner:
int mod(int x, int m) => (x % m) switch
{
< 0 and var r => r + m, var r => r
}
Related
I'm looking for the algorithm to convert a lotto ticket number to an integer value an back again.
Let's say the lotto number can be between 1 and 45 and a tickets contains 6 unique numbers. This means there are a maximum of 8145060 unique lotto tickets.
eg:
01-02-03-04-05-06 = 1
01-02-03-04-05-07 = 2
.
.
.
39-41-42-43-44-45 = 8145059
40-41-42-43-44-45 = 8145060
I'd like to have a function (C# preferable but any language will do) which converts between a lotto ticket and an integer and back again. At the moment I use the quick and dirty method of pre-calculating everything, which needs a lot of memory.
For enumerating integer combinations, you need to use the combinatorial number system. Here's a basic implementation in C#:
using System;
using System.Numerics;
using System.Collections.Generic;
public class CombinatorialNumberSystem
{
// Helper functions for calculating values of (n choose k).
// These are not optimally coded!
// ----------------------------------------------------------------------
protected static BigInteger factorial(int n) {
BigInteger f = 1;
while (n > 1) f *= n--;
return f;
}
protected static int binomial(int n, int k) {
if (k > n) return 0;
return (int)(factorial(n) / (factorial(k) * factorial(n-k)));
}
// In the combinatorial number system, a combination {c_1, c_2, ..., c_k}
// corresponds to the integer value obtained by adding (c_1 choose 1) +
// (c_2 choose 2) + ... + (c_k choose k)
// NOTE: combination values are assumed to start from zero, so
// a combination like {1, 2, 3, 4, 5} will give a non-zero result
// ----------------------------------------------------------------------
public static int combination_2_index(int[] combo) {
int ix = 0, i = 1;
Array.Sort(combo);
foreach (int c in combo) {
if (c > 0) ix += binomial(c, i);
i++;
}
return ix;
}
// The reverse of this process is a bit fiddly. See Wikipedia for an
// explanation: https://en.wikipedia.org/wiki/Combinatorial_number_system
// ----------------------------------------------------------------------
public static int[] index_2_combination(int ix, int k) {
List<int> combo_list = new List<int>();
while (k >= 1) {
int n = k - 1;
if (ix == 0) {
combo_list.Add(n);
k--;
continue;
}
int b = 0;
while (true) {
// (Using a linear search here, but a binary search with
// precomputed binomial values would be faster)
int b0 = b;
b = binomial(n, k);
if (b > ix || ix == 0) {
ix -= b0;
combo_list.Add(n-1);
break;
}
n++;
}
k--;
}
int[] combo = combo_list.ToArray();
Array.Sort(combo);
return combo;
}
}
The calculations are simpler if you work with combinations of integers that start from zero, so for example:
00-01-02-03-04-05 = 0
00-01-02-03-04-06 = 1
.
.
.
38-40-41-42-43-44 = 8145058
39-40-41-42-43-44 = 8145059
You can play around with this code at ideone if you like.
there seem to be actually 45^6 distinct numbers, a simple way is to treat the ticket number as a base-45 number and convert it to base 10:
static ulong toDec(string input){
ulong output = 0;
var lst = input.Split('-').ToList();
for (int ix =0; ix< lst.Count; ix++)
{
output = output + ( (ulong.Parse(lst[ix])-1) *(ulong) Math.Pow(45 , 5-ix));
}
return output;
}
examples:
01-01-01-01-01-01 => 0
01-01-01-01-01-02 => 1
01-01-01-01-02-01 => 45
45-45-45-45-45-45 => 8303765624
All numbers that divide evenly into x.
I put in 4 it returns: 4, 2, 1
edit: I know it sounds homeworky. I'm writing a little app to populate some product tables with semi random test data. Two of the properties are ItemMaximum and Item Multiplier. I need to make sure that the multiplier does not create an illogical situation where buying 1 more item would put the order over the maximum allowed. Thus the factors will give a list of valid values for my test data.
edit++:
This is what I went with after all the help from everyone. Thanks again!
edit#: I wrote 3 different versions to see which I liked better and tested them against factoring small numbers and very large numbers. I'll paste the results.
static IEnumerable<int> GetFactors2(int n)
{
return from a in Enumerable.Range(1, n)
where n % a == 0
select a;
}
private IEnumerable<int> GetFactors3(int x)
{
for (int factor = 1; factor * factor <= x; factor++)
{
if (x % factor == 0)
{
yield return factor;
if (factor * factor != x)
yield return x / factor;
}
}
}
private IEnumerable<int> GetFactors1(int x)
{
int max = (int)Math.Ceiling(Math.Sqrt(x));
for (int factor = 1; factor < max; factor++)
{
if(x % factor == 0)
{
yield return factor;
if(factor != max)
yield return x / factor;
}
}
}
In ticks.
When factoring the number 20, 5 times each:
GetFactors1-5,445,881
GetFactors2-4,308,234
GetFactors3-2,913,659
When factoring the number 20000, 5 times each:
GetFactors1-5,644,457
GetFactors2-12,117,938
GetFactors3-3,108,182
pseudocode:
Loop from 1 to the square root of the number, call the index "i".
if number mod i is 0, add i and number / i to the list of factors.
realocode:
public List<int> Factor(int number)
{
var factors = new List<int>();
int max = (int)Math.Sqrt(number); // Round down
for (int factor = 1; factor <= max; ++factor) // Test from 1 to the square root, or the int below it, inclusive.
{
if (number % factor == 0)
{
factors.Add(factor);
if (factor != number/factor) // Don't add the square root twice! Thanks Jon
factors.Add(number/factor);
}
}
return factors;
}
As Jon Skeet mentioned, you could implement this as an IEnumerable<int> as well - use yield instead of adding to a list. The advantage with List<int> is that it could be sorted before return if required. Then again, you could get a sorted enumerator with a hybrid approach, yielding the first factor and storing the second one in each iteration of the loop, then yielding each value that was stored in reverse order.
You will also want to do something to handle the case where a negative number passed into the function.
The % (remainder) operator is the one to use here. If x % y == 0 then x is divisible by y. (Assuming 0 < y <= x)
I'd personally implement this as a method returning an IEnumerable<int> using an iterator block.
Very late but the accepted answer (a while back) didn't not give the correct results.
Thanks to Merlyn, I got now got the reason for the square as a 'max' below the corrected sample. althought the answer from Echostorm seems more complete.
public static IEnumerable<uint> GetFactors(uint x)
{
for (uint i = 1; i * i <= x; i++)
{
if (x % i == 0)
{
yield return i;
if (i != x / i)
yield return x / i;
}
}
}
As extension methods:
public static bool Divides(this int potentialFactor, int i)
{
return i % potentialFactor == 0;
}
public static IEnumerable<int> Factors(this int i)
{
return from potentialFactor in Enumerable.Range(1, i)
where potentialFactor.Divides(i)
select potentialFactor;
}
Here's an example of usage:
foreach (int i in 4.Factors())
{
Console.WriteLine(i);
}
Note that I have optimized for clarity, not for performance. For large values of i this algorithm can take a long time.
Another LINQ style and tying to keep the O(sqrt(n)) complexity
static IEnumerable<int> GetFactors(int n)
{
Debug.Assert(n >= 1);
var pairList = from i in Enumerable.Range(1, (int)(Math.Round(Math.Sqrt(n) + 1)))
where n % i == 0
select new { A = i, B = n / i };
foreach(var pair in pairList)
{
yield return pair.A;
yield return pair.B;
}
}
Here it is again, only counting to the square root, as others mentioned. I suppose that people are attracted to that idea if you're hoping to improve performance. I'd rather write elegant code first, and optimize for performance later, after testing my software.
Still, for reference, here it is:
public static bool Divides(this int potentialFactor, int i)
{
return i % potentialFactor == 0;
}
public static IEnumerable<int> Factors(this int i)
{
foreach (int result in from potentialFactor in Enumerable.Range(1, (int)Math.Sqrt(i))
where potentialFactor.Divides(i)
select potentialFactor)
{
yield return result;
if (i / result != result)
{
yield return i / result;
}
}
}
Not only is the result considerably less readable, but the factors come out of order this way, too.
I did it the lazy way. I don't know much, but I've been told that simplicity can sometimes imply elegance. This is one possible way to do it:
public static IEnumerable<int> GetDivisors(int number)
{
var searched = Enumerable.Range(1, number)
.Where((x) => number % x == 0)
.Select(x => number / x);
foreach (var s in searched)
yield return s;
}
EDIT: As Kraang Prime pointed out, this function cannot exceed the limit of an integer and is (admittedly) not the most efficient way to handle this problem.
Wouldn't it also make sense to start at 2 and head towards an upper limit value that's continuously being recalculated based on the number you've just checked? See N/i (where N is the Number you're trying to find the factor of and i is the current number to check...) Ideally, instead of mod, you would use a divide function that returns N/i as well as any remainder it might have. That way you're performing one divide operation to recreate your upper bound as well as the remainder you'll check for even division.
Math.DivRem
http://msdn.microsoft.com/en-us/library/wwc1t3y1.aspx
If you use doubles, the following works: use a for loop iterating from 1 up to the number you want to factor. In each iteration, divide the number to be factored by i. If (number / i) % 1 == 0, then i is a factor, as is the quotient of number / i. Put one or both of these in a list, and you have all of the factors.
And one more solution. Not sure if it has any advantages other than being readable..:
List<int> GetFactors(int n)
{
var f = new List<int>() { 1 }; // adding trivial factor, optional
int m = n;
int i = 2;
while (m > 1)
{
if (m % i == 0)
{
f.Add(i);
m /= i;
}
else i++;
}
// f.Add(n); // adding trivial factor, optional
return f;
}
I came here just looking for a solution to this problem for myself. After examining the previous replies I figured it would be fair to toss out an answer of my own even if I might be a bit late to the party.
The maximum number of factors of a number will be no more than one half of that number.There is no need to deal with floating point values or transcendent operations like a square root. Additionally finding one factor of a number automatically finds another. Just find one and you can return both by just dividing the original number by the found one.
I doubt I'll need to use checks for my own implementation but I'm including them just for completeness (at least partially).
public static IEnumerable<int>Factors(int Num)
{
int ToFactor = Num;
if(ToFactor == 0)
{ // Zero has only itself and one as factors but this can't be discovered through division
// obviously.
yield return 0;
return 1;
}
if(ToFactor < 0)
{// Negative numbers are simply being treated here as just adding -1 to the list of possible
// factors. In practice it can be argued that the factors of a number can be both positive
// and negative, i.e. 4 factors into the following pairings of factors:
// (-4, -1), (-2, -2), (1, 4), (2, 2) but normally when you factor numbers you are only
// asking for the positive factors. By adding a -1 to the list it allows flagging the
// series as originating with a negative value and the implementer can use that
// information as needed.
ToFactor = -ToFactor;
yield return -1;
}
int FactorLimit = ToFactor / 2; // A good compiler may do this optimization already.
// It's here just in case;
for(int PossibleFactor = 1; PossibleFactor <= FactorLimit; PossibleFactor++)
{
if(ToFactor % PossibleFactor == 0)
{
yield return PossibleFactor;
yield return ToFactor / PossibleFactor;
}
}
}
Program to get prime factors of whole numbers in javascript code.
function getFactors(num1){
var factors = [];
var divider = 2;
while(num1 != 1){
if(num1 % divider == 0){
num1 = num1 / divider;
factors.push(divider);
}
else{
divider++;
}
}
console.log(factors);
return factors;
}
getFactors(20);
In fact we don't have to check for factors not to be square root in each iteration from the accepted answer proposed by chris fixed by Jon, which could slow down the method when the integer is large by adding an unnecessary Boolean check and a division. Just keep the max as double (don't cast it to an int) and change to loop to be exclusive not inclusive.
private static List<int> Factor(int number)
{
var factors = new List<int>();
var max = Math.Sqrt(number); // (store in double not an int) - Round down
if (max % 1 == 0)
factors.Add((int)max);
for (int factor = 1; factor < max; ++factor) // (Exclusice) - Test from 1 to the square root, or the int below it, inclusive.
{
if (number % factor == 0)
{
factors.Add(factor);
//if (factor != number / factor) // (Don't need check anymore) - Don't add the square root twice! Thanks Jon
factors.Add(number / factor);
}
}
return factors;
}
Usage
Factor(16)
// 4 1 16 2 8
Factor(20)
//1 20 2 10 4 5
And this is the extension version of the method for int type:
public static class IntExtensions
{
public static IEnumerable<int> Factors(this int value)
{
// Return 2 obvious factors
yield return 1;
yield return value;
// Return square root if number is prefect square
var max = Math.Sqrt(value);
if (max % 1 == 0)
yield return (int)max;
// Return rest of the factors
for (int i = 2; i < max; i++)
{
if (value % i == 0)
{
yield return i;
yield return value / i;
}
}
}
}
Usage
16.Factors()
// 4 1 16 2 8
20.Factors()
//1 20 2 10 4 5
Linq solution:
IEnumerable<int> GetFactors(int n)
{
Debug.Assert(n >= 1);
return from i in Enumerable.Range(1, n)
where n % i == 0
select i;
}
For example, the pairs that multiple to 16 are {(16,1), (2,8), (4,4)} and the pairs that multiply to 15 are {(15,1), (5,3)} but I'm not of how to construct an algorithm better than brute force. My method looks like
private static IEnumerable<Tuple<int, int>> Multipliers(int m)
{
var found = new HashSet<int>();
foreach(int v in Enumerable.Range(1, m))
{
int d = m / v;
bool even = m % v == 0;
if(even && found.Contains(d))
{
yield return Tuple.Create(d, v);
}
found.Add(v);
}
}
which is sloppy and probably not as efficient as possible.
Here's a sample method for you, though I'm not sure if it's the "most efficient one", per se:
public static IEnumerable<(int A, int B)> Multipliers(int m)
{
yield return (m, 1);
int i = 2;
int lastVal = m / 2;
while (i <= lastVal)
{
if (m % i == 0)
{
lastVal = m / i;
yield return (lastVal, i);
}
i++;
}
}
public static void Main(string[] args)
{
foreach (var pair in Multipliers(16))
{
Console.WriteLine("{0}, {1}", pair.A, pair.B);
}
}
Using C#7 tuple return syntax because I can. :P
EDIT: Switched from a for loop to a while loop to handle the case for when m <= 2.
EDIT 2: As suggested by Adwaenyth, this is a midified version of the method that checks if m is even. If not, then skip all even potential factors. Also, as suggested by other answers, limit the iteration to the square root of m instead of m/2:
public static IEnumerable<(int A, int B)> Multipliers(int m)
{
yield return (m, 1);
int lastVal = (int)Math.Sqrt(m);
int increment = (m % 2 != 0) ? 2 : 1;
int i = (m % 2 != 0) ? 3 : 2;
while (i <= lastVal)
{
if (m % i == 0)
{
lastVal = m / i;
yield return (lastVal, i);
}
i += increment;
}
}
I'm pretty sure that this is as efficient as this particular approach can go. To make it better, you would tweak it to check against all prime numbers and their multiples up to the square root of m. Ideally, you would do this against a look-up table, since a lot of the time you save by only comparing prime numbers would be lost while generating them. (For really large ms, it still comes out faster, though.)
EDIT 3 I discovered that my previous code's use of lastVal was making the required time be a bit inconsistent as well as introducing a weird bug that made it sometimes forget to check larger factors. Here's an update that should fix those problems:
public static IEnumerable<(int A, int B)> Multipliers(int m)
{
yield return (m, 1);
int finalVal = (int)Math.Sqrt(m);
int increment = m % 2 != 0 ? 2 : 1;
int i = m % 2 != 0 ? 3 : 2;
while (i <= finalVal)
{
if (m % i == 0)
{
yield return (m / i, i);
}
i += increment;
}
}
First generate a list of primes up to the square root of input N you will have, for each prime p check if it divides N. If it does then N = N/p and repeat this recursively until all primes in list has have been exhausted or N/p = 1.
In the rare case of where no primes in list can divide the input, then your number is a prime. The only pairs are {(1, N), (N, 1)}. This should get more rare as your input increases exponentially.
For the other case count all the prime divisors and the times they occur. Finally find all combination of products of the primes up to square root of N, which will all be part of pairs that divide N.
I think that the best way to do this is perform prime factorization algorithm. But you should note that it is very difficult area of mathematics. You can find articles in http://mathworld.wolfram.com/PrimeFactorizationAlgorithms.html
From sequence of prime numbers you can combine all possible pairs which form given number
This question already has answers here:
How to round a integer to the close hundred?
(10 answers)
Closed 5 years ago.
I'm trying to find some Math using for such rounding, if it is exist as method:
3219 to 3300
11380 to 11400
12583 to 12600
8275 to 8300
1778 to 1800
399 to 400
340 to 400
305 to 400
266 to 300
123 to 200
32 to 100
3 to 100
1 to 100
Based on your example, you want to round up to the closest 100, you can do this with:
int x = 3219; // or any other input
int result = (x+99)/100*100;
The advantage of this algorithm is that you stay in the integer world. So that means that there are no rounding errors (and as long as the subresult can be represented as an integer), we are fine.
You can generalize this method like:
public static int RoundUp(this int x, int n = 100) {
return (x+n-1)/n*n;
}
Where n is the number to which you want to round up.
Based on #wenstons answer, you can construct a branchfree algorithm that suffers less from integer overflow:
public static int RoundUp(this int x, int n = 100) {
int r = x % n;
return x + (n - r) % n;
}
Use this:
var value = 1234;
var result = (int)(Math.Ceiling(value/100f)*100);
In order to prevent integer overflow issues with intermediate results (e.g. RoundUp(2147482999, 1000)) we should not add n to x before the divide:
public static int RoundUp(int x, int n) {
var r = x % n;
if (r == 0) return x;
return x + n - r;
}
x % n is the remainder of a divide. If this is non-zero, we need to add the compliment of this (n - x % n) which is in the range [1..n]. When it is == n, we actually want it to add zero, so we can achieve this by another % n as Willem pointed out, which makes it branchless but with two mods instead of one.
public static int RoundUp(int x, int n) {
return x + (n - x % n) % n;
}
And, just a reminder, if you really care about integer overflow beyond this, then you can wrap in a checked block:
public static int RoundUp(int x, int n) {
checked
{
return x + (n - x % n) % n;
}
}
Is there a simple math function available that compares numbers x and y and returns -1 when x is less than y, 1 when x is more than y and 0 when they're equal?
If not, would there be a elegant solution (without any if's) to convert the output of Math.Max(x, y) to these returns? I was thinking of dividing the numbers by themselves, e.g. 123/123 = 1 but that will introduce the problem of dividing by 0.
For your strict -1, 0 or 1 requirement, there's no single method that is guaranteed to do this. However, you can use a combination of Int32.CompareTo and Math.Sign:
int value = Math.Sign(x.CompareTo(y));
Alternatively, if you're happy with the normal CompareTo contract which is just stated in terms of negative numbers, positive numbers and 0, you can use CompareTo on its own.
You can do it without using any .NET calls at all and on 1 line. NOTE: Math.Sign and type.CompareTo both use logical if statements and comparison operators which you said you wanted to avoid.
int result = (((x - y) >> 0x1F) | (int)((uint)(-(x - y)) >> 0x1F));
as a function
//returns 0 if equal
//returns 1 if x > y
//returns -1 if x < y
public int Compare(int x, int y)
{
return (((x - y) >> 0x1F) | (int)((uint)(-(x - y)) >> 0x1F));
}
Basically, all this does is SHIFT the sign bits all the way to the first position. If the result is unsigned then it will be 0; then it does the same operation and flips the sign bits then ORs them together and the result is wither 1, 0 or -1.
Case where result is -1
IS 12 > 15:
12 - 15 = -3 (11111111111111111111111111111101)
-3 >> 0x1F = -1 (11111111111111111111111111111111)
-(12 - 15) = 3 (00000000000000000000000000000011)
3 >> 0x1F = ((uint)0)=0 (00000000000000000000000000000000) cast to uint so 0
11111111111111111111111111111111
OR
00000000000000000000000000000000
= 11111111111111111111111111111111 (-1)
Case where result is 1
IS 15 > 12:
15 - 12 = 3 (00000000000000000000000000000011)
3 >> 0x1F = 0 (00000000000000000000000000000000)
-(15 - 12) = -3 (11111111111111111111111111111101)
-3 >> 0x1F = ((uint)-1)=1 (00000000000000000000000000000001) cast to uint so 1
00000000000000000000000000000000
OR
00000000000000000000000000000001
= 00000000000000000000000000000001 (1)
Case where result is 0
IS 15 == 15:
15 - 15 = 0 (00000000000000000000000000000000)
0 >> 0x1F = 0 (00000000000000000000000000000000)
-(15 - 15) = 0 (00000000000000000000000000000000)
0 >> 0x1F = ((uint)0)=0 (00000000000000000000000000000000) cast to uint so 1
00000000000000000000000000000000
OR
00000000000000000000000000000000
= 00000000000000000000000000000000 (0)
This should also be much faster than using any calls to Math or any other .NET methods.
x.CompareTo(y)
Straight from MSDN.
Use the CompareTo() function
int i = 5;
int n = 6;
int c = i.CompareTo(n);
I generally use it in if statements:
int x = 34;
int y = 25;
if(x.CompareTo(y) == 0)
{
Console.WriteLine("Yes, they are equal");
}
else
{
Console.WriteLine("No, they are not equal");
}
Edit:
After some people claimed that Int32.CompareTo() could return something other than -1|0|1, I decided to research the possibility myself.
Here's the reflected code for Int32.CompareTo(). I fail to see how either one would ever return anything but -1|0|1.
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public int CompareTo(int value)
{
if (this < value)
{
return -1;
}
if (this > value)
{
return 1;
}
return 0;
}
public int CompareTo(object value)
{
if (value == null)
{
return 1;
}
if (!(value is int))
{
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeInt32"));
}
int num = (int) value;
if (this < num)
{
return -1;
}
if (this > num)
{
return 1;
}
return 0;
}
It's the Math.Sign() function.
Like this:
return Math.Sign(x-y);
you can try with this code
var result = a.CompareTo(b);
Use the CompareTo Method on an integer:
public int c(int x, int y)
{
return x.CompareTo(y);
}
void Main()
{
Console.WriteLine(c(5,3));
Console.WriteLine(c(3,3));
Console.WriteLine(c(1,3));
}
You tried use compareTo()? Look here: http://msdn.microsoft.com/en-us/library/y2ky8xsk.aspx