Getting the nearest multiple of x of an integer thats equal or greater than the original value - c++

Lets say I have x = 25 and y = 4. I want the nearest value to x that is a) multiple of y and b) equal or greater than x, for these numbers it would be 28. Usually I would do this:
result = ceil((float)x / (float)y) * y
however, this time I'm dealing with uint64's and rather large numbers that would probably get chewed up by the conversion to a double and back so currently I'm doing this:
if (x % y) result = (x / y + 1) * y
else result = x
but I'm wondering if theres a better way since this has to come up a lot when dealing with files (i know it does for me)

I'd do it this way:
z = x%y;
result = x + (z? y-z: 0);
No multiplication or division, and no danger of overflow (if the correct result can fit in the type).

Related

How can you calculate a factor if you have the other factor and the product with overflows?

a * x = b
I have a seemingly rather complicated multiplication / imul problem: if I have a and I have b, how can I calculate x if they're all 32-bit dwords (e.g. 0-1 = FFFFFFFF, FFFFFFFF+1 = 0)?
For example:
0xcb9102df * x = 0x4d243a5d
In that case, x is 0x1908c643. I found a similar question but the premises were different and I'm hoping there's a simpler solution than those given.
Numbers have a modular multiplicative inverse modulo a power of two precisely iff they are odd. Everything else is a bit-shifted odd number (even zero, which might be anything, with all bits shifted out). So there are a couple of cases:
Given a * x = b
tzcnt(a) > tzcnt(b) no solution
tzcnt(a) <= tzcnt(b) solvable, with 2tzcnt(a) solutions
The second case has a special case with 1 solution, for odd a, namely x = inverse(a) * b
More generally, x = inverse(a >> tzcnt(a)) * (b >> tzcnt(a)) is a solution, because you write a as (a >> tzcnt(a)) * (1 << tzcnt(a)), so we cancel the left factor with its inverse, we leave the right factor as part of the result (cannot be cancelled anyway) and then multiply by what remains to get it up to b. Still only works in the second case, obviously. If you wanted, you could enumerate all solutions by filling in all possibilities for the top tzcnt(a) bits.
The only thing that remains is getting the inverse, you've probably seen it in the other answer, whatever it was, but for completeness you can compute it as follows: (not tested)
; input x
dword y = (x * x) + x - 1;
dword t = y * x;
y *= 2 - t;
t = y * x;
y *= 2 - t;
t = y * x;
y *= 2 - t;
; result y

Calculating index in a subdivided interval?

Consider an interval of values [x, y] equally subdivided in n samples in the following way:
y can be greater, equal or less than x.
Now, we pick up a value z between x and y.
Question: what is the formula to compute the index i of z ? (if x = y, then the formula should return 0 or n-1) (I repeat: y can be greater, equal or less than x.)
For example: if x = - 5, y = -10 and n = 5, then for z = -7.5, i = 2 (if z = -7, i = 2 but if z = -8, i = 3).
You can compute the length of the interval as:
len = y - x
Then you can compute the increase per a single element
increase = len / n;
And now you have i = (z - x) / increase. In short you compute how much does the value increase per a single element and than you compute how many times this increase is needed to get from x to z.
EDIT: if you really require the solution in C++ take care to do all the calculations in double. Also please note the value of i should be an integer rounded down.
Answer logic(IN java):
i = Math.abs(Math.ceil(z - Math.min(x,y)));
if(x>y) high = x low = y
else high = y low = x
if(y>=x)
i = ceil((z-low+1)/(high-low+1)*n)-1
else i = ceil((high-z+1)/(high-low+1)*n)-1

Need clarification about this loop performing multiplication

int x, y; // x is a non-negative integer
p = 0;
while (x > 0)
{
if ( x % 2 == 1 )
p = p + y;
y = y*2;
x = x/2;
}
// p == a*b here
I understand that this loop finds the product of 'a' and 'b' using the algebra:
a * b = (1/2)a * 2b
but I don't understand the code:
if ( x % 2 == 1 )
p = p + y;
I was hoping someone could explain why 'p' is assigned 'p + y' on odd values of x.
while (x > 0) {
if (x % 2 == 1)
p = p + y;
y = y*2;
x = x/2;
}
imagine x = 4, y = 5
iterations:
x is even, y = 10, x = 2 (i.e. x can be divided, y should be doubled)
x is even, y = 20, x = 1
x is odd, p = 20, y = 40, x = 0 (i.e. x can not be divided anymore, y should be added to p)
x > 0 is false, loop ends
p = 4 * y
now imagine x is odd at the beginning, let's say x = 5, y = 2:
x is odd, p = 2, y = 4, x = 2
(5/2 = 2.5, new value of x will be rounded down, y should be added BEFORE it is doubled)
x is even, y = 8, x = 1
x is odd, p = 10, y = 16, x = 0
p = y + 4*y
that first y is the reason, adding it to the result before it is doubled (1 * y) is in this case equivalent to 0.5 * (2 * y)
Because these are integers, a / 2 will be an integer. If a is odd, that integer has been rounded down, and you’re missing one-half b in the next iteration of the loop, i.e. one whole b in the current iteration of the loop (since b [y] is doubled each time).
If x is odd, x = x/2 will set x to 0.5 less than x/2 (because integer division rounds it down). p needs to be adjusted to allow for that.
Think of multiplication as repeated addition, x*y is adding y together x times. It is also the same as adding 2*y together x/2 times. Conceptually it is somewhat unclear what it means if x is odd. For example, if x=5 and y=3, what does it mean to add 2.5 times? The code notices when x is odd, adds y in, then does the y=y*2 and x=x/2. When x is odd, this throws away the .5 part. So in this example, you add y one time, then x becomes 2 (not 2.5) because integer division throws away the fraction.
At the end of each loop, you will see that the product of the original x and y is equal to p + x*y for the current values of p, x, and y. The loop iterates until x is 0, and the result is entirely in p.
It also helps to see what is going on if you make a table and update it each time through the loop. These are the values at the start of each iteration:
x | y | p
----------
5 | 3 | 0
2 | 6 | 3
1 | 12 | 3
0 | 24 | 15
This works by observing that (for example) y * 10 = y * 8 + y * 2.
It's pretty much like doing multiplication on paper in school. For example, to multiply 14 x 21, we multiply one digit at a time (and shift left a place where needed) so we add 1x14 + 2 x 14 (shifted left one digit).
14
x 21
----
14
280
Here, we're doing pretty much the same thing, but working in binary instead of decimal. The right shifting has nothing to do with the numbers being odd, and everything to do with simply finding which bits in the number are set.
As we shift one operand right to find whether a bit is set, we also shift the other operand left, just like we add zeros to shift numbers left when doing arithmetic on paper in decimal.
So, viewing things in binary, we end up with something like:
101101
x 11010
--------
1011010
+ 101101000
+ 1011010000
If we wanted to, instead of shifting the operand right, we could just shift the mask left so instead of repeatedly anding with 1, we'd and with 1, then with 2, then with 4, and so on (in fact, it would probably make a lot more sense that way). For better or worse, however, in assembly language (where this sort of thing is normally done) it's usually a little easier to shift the operand and use a constant for the mask than load the mask in a register and shift it when needed.
You should rewrite x as 2*b+1 (assuming x is odd). Then
x*y = (2*b+1)*y = (2*b)*y + y = b*(2*y) + y = (x/2)*(2*y) + y
where (x/2) is meant to be the integer division. With the operation rewritten this way, you see the x/2, the 2y and the +y appear.

Finding solution set of a Linear equation?

I need to find all possible solutions for this equation:
x+2y = N, x<100000 and y<100000.
given N=10, say.
I'm doing it like this in python:
for x in range(1,100000):
for y in range(1,100000):
if x + 2*y == 10:
print x, y
How should I optimize this for speed? What should I do?
Essentially this is a Language-Agnostic question. A C/C++ answer would also help.
if x+2y = N, then y = (N-x)/2 (supposing N-x is even). You don't need to iterate all over range(1,100000)
like this (for a given N)
if (N % 2): x0 = 1
else: x0 = 0
for x in range(x0, min(x,100000), 2):
print x, (N-x)/2
EDIT:
you have to take care that N-x does not turn negative. That's what min is supposed to do
The answer of Leftris is actually better than mine because these special cases are taken care of in an elegant way
we can iterate over the domain of y and calculate x. Also taking into account that x also has a limited range, we further limit the domain of y as [1, N/2] (as anything over N/2 for y will give negative value for x)
x=N;
for y in range(1,N/2-1):
x = x-2
print x, y
This just loops N/2 times (instead of 50000)
It doesn't even do those expensive multiplications and divisions
This runs in quadratic time. You can reduce it to linear time by rearranging your equation to the form y = .... This allows you to loop over x only, calculate y, and check whether it's an integer.
Lefteris E 's answer is the way to go,
but I do feel y should be in the range [1,N/2] instead of [1,2*N]
Explanation:
x+2*y = N
//replace x with N-2*y
N-2*(y) + 2*y = N
N-2*(N/2) + 2*y = N
2*y = N
//therefore, when x=0, y is maximum, and y = N/2
y = N/2
So now you can do:
for y in range(1,int(N/2)):
x = N - (y<<1)
print x, y
You may try to only examine even numbers for x given N =10;
the reason is that: 2y must be even, therefore, x must be even. This should reduce the total running time to half of examining all x.
If you also require that the answer is natural number, so negative numbers are ruled out. you can then only need to examine numbers that are even between [0,10] for x, since both x and 2y must be not larger than 10 alone.

Fast ceiling of an integer division in C / C++

Given integer values x and y, C and C++ both return as the quotient q = x/y the floor of the floating point equivalent. I'm interested in a method of returning the ceiling instead. For example, ceil(10/5)=2 and ceil(11/5)=3.
The obvious approach involves something like:
q = x / y;
if (q * y < x) ++q;
This requires an extra comparison and multiplication; and other methods I've seen (used in fact) involve casting as a float or double. Is there a more direct method that avoids the additional multiplication (or a second division) and branch, and that also avoids casting as a floating point number?
For positive numbers where you want to find the ceiling (q) of x when divided by y.
unsigned int x, y, q;
To round up ...
q = (x + y - 1) / y;
or (avoiding overflow in x+y)
q = 1 + ((x - 1) / y); // if x != 0
For positive numbers:
q = x/y + (x % y != 0);
Sparky's answer is one standard way to solve this problem, but as I also wrote in my comment, you run the risk of overflows. This can be solved by using a wider type, but what if you want to divide long longs?
Nathan Ernst's answer provides one solution, but it involves a function call, a variable declaration and a conditional, which makes it no shorter than the OPs code and probably even slower, because it is harder to optimize.
My solution is this:
q = (x % y) ? x / y + 1 : x / y;
It will be slightly faster than the OPs code, because the modulo and the division is performed using the same instruction on the processor, because the compiler can see that they are equivalent. At least gcc 4.4.1 performs this optimization with -O2 flag on x86.
In theory the compiler might inline the function call in Nathan Ernst's code and emit the same thing, but gcc didn't do that when I tested it. This might be because it would tie the compiled code to a single version of the standard library.
As a final note, none of this matters on a modern machine, except if you are in an extremely tight loop and all your data is in registers or the L1-cache. Otherwise all of these solutions will be equally fast, except for possibly Nathan Ernst's, which might be significantly slower if the function has to be fetched from main memory.
You could use the div function in cstdlib to get the quotient & remainder in a single call and then handle the ceiling separately, like in the below
#include <cstdlib>
#include <iostream>
int div_ceil(int numerator, int denominator)
{
std::div_t res = std::div(numerator, denominator);
return res.rem ? (res.quot + 1) : res.quot;
}
int main(int, const char**)
{
std::cout << "10 / 5 = " << div_ceil(10, 5) << std::endl;
std::cout << "11 / 5 = " << div_ceil(11, 5) << std::endl;
return 0;
}
There's a solution for both positive and negative x but only for positive y with just 1 division and without branches:
int div_ceil(int x, int y) {
return x / y + (x % y > 0);
}
Note, if x is positive then division is towards zero, and we should add 1 if reminder is not zero.
If x is negative then division is towards zero, that's what we need, and we will not add anything because x % y is not positive
How about this? (requires y non-negative, so don't use this in the rare case where y is a variable with no non-negativity guarantee)
q = (x > 0)? 1 + (x - 1)/y: (x / y);
I reduced y/y to one, eliminating the term x + y - 1 and with it any chance of overflow.
I avoid x - 1 wrapping around when x is an unsigned type and contains zero.
For signed x, negative and zero still combine into a single case.
Probably not a huge benefit on a modern general-purpose CPU, but this would be far faster in an embedded system than any of the other correct answers.
I would have rather commented but I don't have a high enough rep.
As far as I am aware, for positive arguments and a divisor which is a power of 2, this is the fastest way (tested in CUDA):
//example y=8
q = (x >> 3) + !!(x & 7);
For generic positive arguments only, I tend to do it like so:
q = x/y + !!(x % y);
This works for positive or negative numbers:
q = x / y + ((x % y != 0) ? !((x > 0) ^ (y > 0)) : 0);
If there is a remainder, checks to see if x and y are of the same sign and adds 1 accordingly.
simplified generic form,
int div_up(int n, int d) {
return n / d + (((n < 0) ^ (d > 0)) && (n % d));
} //i.e. +1 iff (not exact int && positive result)
For a more generic answer, C++ functions for integer division with well defined rounding strategy
For signed or unsigned integers.
q = x / y + !(((x < 0) != (y < 0)) || !(x % y));
For signed dividends and unsigned divisors.
q = x / y + !((x < 0) || !(x % y));
For unsigned dividends and signed divisors.
q = x / y + !((y < 0) || !(x % y));
For unsigned integers.
q = x / y + !!(x % y);
Zero divisor fails (as with a native operation). Cannot cause overflow.
Corresponding floored and modulo constexpr implementations here, along with templates to select the necessary overloads (as full optimization and to prevent mismatched sign comparison warnings):
https://github.com/libbitcoin/libbitcoin-system/wiki/Integer-Division-Unraveled
Compile with O3, The compiler performs optimization well.
q = x / y;
if (x % y) ++q;