How to compute distance between numbers in c++? - c++

I want to compute the distance between numbers with help of the system described in the attached image.
For example: distance between 7 and 5 is -2, distance between 7 and 1 is 2 etc...
Any ideas how to do this in c++? The prefered direction is counter clockwise...
I am using a (int) vector.

If you do it in straightforward way (by considering all possibilities) it might look as follows
int distance(int a, int b)
{ // Distance from `a` to `b`
int d = b - a;
return
a <= b ?
(d <= +4 ? d : d - 8) :
(d <= -4 ? d + 8 : d);
}
which, if you prefer, can be rewritten as
int distance(int a, int b)
{ // Distance from `a` to `b`
int d = b - a;
return -4 < d && d <= 4 ? d : (d > 0 ? d - 8 : d + 8);
}
An alternative, more elegant approach would be to always calculate the positive CCW distance and flip it to negative CW distance if it is greater than 4
int distance(int a, int b)
{ // Distance from `a` to `b`
int d = (b + 8 - a) % 8;
// `d` is CCW distance from `a` to `b`
return d <= 4 ? d : d - 8;
}
But if you want the compiler to generate the most efficient code for this, follow the golden rule "use unsigned types everywhere you can, use signed types only if you have to":
int distance(unsigned a, unsigned b)
{ // Distance from `a` to `b`
unsigned d = (b + 8 - a) % 8;
// `d` is CCW distance from `a` to `b`
return d <= 4 ? d : (int) d - 8;
}

These are really complicated answers. Here is a simpler one:
int distance(int x, int y) {
int d = (y - x) & 7;
return d > 4 ? d - 8 : d;
}
This always returns a result in the range -3..+4. Modular arithmetic is a little simpler to write when the ring size is a power of two, as is the case here.
distance(7, 5) = -2
distance(5, 7) = +2
distance(6, 2) = +4
distance(2, 6) = +4
We use & 7 because it is the simplest way to get the modulo. Alternatively, you can use % 8, but you must also add 8 in order to make sure that the input is not negative:
int d = (y - x + 8) % 8; // same result
Alternatively, you can handle negative numbers explicitly:
int d = (y - x) % 8;
if (d < 0) {
d += 8;
}
// same result
This is just a matter of style.

For simplicity you can find the element from std::find and get the distance from start from std::distance
for example
as you mentioned the data saved in int vector
std::vector<int>::iterator it1 = std::find(myvec.begin(), myvec.end(), val_1);
std::vector<int>::iterator it2 = std::find(myvec.begin(), myvec.end(), val_2);
int dist = std::distance(myvec.begin(),it1) - std::distance(myvec.begin.it2);
if(dist < 0) return dist
else(dist > 0) return myvector.size() - dist()
So hope this will give the distance as the image ...

I am pretty sure this works:
list = [0,1,2,3,4,5,6,7]
distance(x,y) {
a = y-x
b = length(list)-abs(y-x)
z = min(abs(a), abs(b))
if(z=abs(a)) { return a }
if(z=abs(b)) { return b }
}
where abs() is the mathematical absolute value function.
I make a few assumptions here.
As #Hédi Ghédiri pointed out, you are not counting counter-clockwise both times. I am assuming you count the shortest path to the number. (I used the mathematical min() function)
You prefer the positive value over the negative value (#Harper's comment). If you prefer the negative value, switch the last two if statements.
There may be a more concise method, but this (hopefully) works. Please comment if it is wrong. Hope this is helpful!
Edit: this is psuedocode. It should be easy to write in c++. Use the abs() function in <stdlib.h> Forget about list and length(list). Use int types for the variables, and everything else should work.

The following code is prepared to meet all of your needs, for example I assume, that if direction is clockwise the distance is to be negative.
#include <iostream>
#define RING_SIZE 8
enum direction
{
clockwise,
counterClockwise
};
int distance(int a, int b, direction dir)
{
int dist;
if(dir == clockwise)
{
if(a>b)
{
dist = -(a-b);
}
else
{
dist =-(RING_SIZE-b+a);
}
}
else
{
if(a<b)
{
dist = b-a;
}
else
{
dist = RING_SIZE-a+b;
}
}
if(a==b) dist = 0;//Add this if distance between same point must to be 0
return dist;
}
int main()
{
std::cout << distance(7, 2, clockwise) << std::endl;
}

I think this should work
int func(a,b)
{
dist=(b-a);
if(dist<0)
dist +=8;
return dist;
}
in case you're really stuck

Related

I encountered the 10^9+7 problem but I can't understand the relation between the distributive properties of mod and my problem

Given 3 numbers a b c get a^b , b^a , c^x where x is abs diff between b and a cout each one but mod 10^9+7 in ascending order.
well I searched web for how to use the distributive property but didn't understand it since I am beginner,
I use very simple for loops so understanding this problem is a bit hard for me so how can I relate these mod rules with powers too in loops? If anyone can help me I would be so happy.
note time limit is 1 second which makes it harder
I tried to mod the result every time in the loop then times it by the original number.
for example if 2^3 then 1st loop given variables cin>>a,a would be 2, num =a would be like this
a = (a % 10^9 + 7) * num this works for very small inputs but large ones it exceed time
#include <iostream>
#include <cmath>
using namespace std;
int main ()
{
long long a,b,c,one,two,thr;
long long x;
long long mod = 1e9+7;
cin>>a>>b>>c;
one = a;
two = b;
thr = c;
if (a>=b)
x = a - b;
else
x = b - a;
for(int i = 0; i < b-1;i++)
{
a = ((a % mod) * (one%mod))%mod;
}
for(int j = 0; j < a-1;j++)
{
b = ((b % mod) * (two%mod))%mod;
}
for(int k = 0; k < x-1;k++)
{
c = ((c % mod) * (thr%mod))%mod;
}
}
I use very simple for loops [...] this works for very small inputs, but large ones it exceeds time.
There is an algorithm called "exponentiation by squaring" that has a logarithmic time complexity, rather then a linear one.
It works breaking down the power exponent while increasing the base.
Consider, e.g. x355. Instead of multiplying x 354 times, we can observe that
x355 = x·x354 = x·(x2)177 = x·x2·(x2)176 = x·x2·(x4)88 = x·x2·(x8)44 = x·x2·(x16)22 = x·x2·(x32)11 = x·x2·x32·(x32)10 = x·x2·x32·(x64)5 = x·x2·x32·x64·(x64)4 = x·x2·x32·x64·(x128)2 = x1·x2·x32·x64·x256
That took "only" 12 steps.
To implement it, we only need to be able to perform modular multiplications safely, without overflowing. Given the value of the modulus, a type like std::int64_t is wide enough.
#include <iostream>
#include <cstdint>
#include <limits>
#include <cassert>
namespace modular
{
auto exponentiation(std::int64_t base, std::int64_t exponent) -> std::int64_t;
}
int main()
{
std::int64_t a, b, c;
std::cin >> a >> b >> c;
auto const x{ b < a ? a - b : b - a };
std::cout << modular::exponentiation(a, b) << '\n'
<< modular::exponentiation(b, a) << '\n'
<< modular::exponentiation(c, x) << '\n';
return 0;
}
namespace modular
{
constexpr std::int64_t M{ 1'000'000'007 };
// We need the mathematical modulo
auto from(std::int64_t x)
{
static_assert(M > 0);
x %= M;
return x < 0 ? x + M : x;
}
// It assumes that both a and b are already mod M
auto multiplication_(std::int64_t a, std::int64_t b)
{
assert( 0 <= a and a < M and 0 <= b and b < M );
assert( b == 0 or a <= std::numeric_limits<int64_t>::max() / b );
return (a * b) % M;
}
// Implements exponentiation by squaring
auto exponentiation(std::int64_t base, std::int64_t exponent) -> std::int64_t
{
assert( exponent >= 0 );
auto b{ from(base) };
std::int64_t x{ 1 };
while ( exponent > 1 )
{
if ( exponent % 2 != 0 )
{
x = multiplication_(x, b);
--exponent;
}
b = multiplication_(b, b);
exponent /= 2;
}
return multiplication_(b, x);
}
}

How to Solve this challenge

I have a circle with points 0-360 the first and last point are connected, take point 11 and 216. Now, give any point how can i find if it is close to 11 or 216. I need a generic algorithm. For example:if given point 20 it should find that its close to 11, and when given 200 it should find close to 216. Till this point its easy but, for point 350 it should find that its close to 11, not 216.
I have this formula but it don't work for the third case:
int find_point(int a){
int temp1=(a>=11?a-11:11-a);
int temp2=(a>=216?a-216:216-a);
if(temp1<temp2)
return 11;
else
return 216;
}
That's the trick with the circle – it's round.
So, there are always two ways to get from one point on a circle to another, a left one and a right one. If the points are not on the same diameter than one way will be shorter than the other.
The other trick is that there is a wrap-around at 360° because 360° and 0° are actually the same angle (because, see above – the circle is round).
An example:
the minimum distance between 5° and 355°:
|355 - 5| = 350
but the correct answer would be 10.
If 360° is added to 5:
|355 - 365| = 10
Hence, my simple idea was to check a, a + 360, and a - 360. So, any wrap-around should be covered. There are some distances computed which might be even above of 360 but they will not hurt because the minimum is searched.
#include <algorithm>
#include <iostream>
int get_dist(int a, int b)
{
return std::min({ abs(a - b), abs(a + 360 - b), abs(a - 360 - b) });
}
int find_point(int a)
{
int d11 = get_dist(a, 11);
int d216 = get_dist(a, 216);
return d11 < d216 ? 11 : 216;
}
int main()
{
std::cout << "20 is closest to " << find_point(20) << '\n';
std::cout << "200 is closest to " << find_point(200) << '\n';
std::cout << "350 is closest to " << find_point(350) << '\n';
}
Output:
20 is closest to 11
200 is closest to 216
350 is closest to 11
Live Demo on coliru
Maybe, not the most elegant but a simple and maintenance-friendly solution (ignoring the magic numbers in the code).
Using some integer magic confined to addition, subtraction, and multiplication:
/* only for systems with 32-bit ints! */
int find_point(int a)
{
a*=11930465;
int distance_to_11 = a-131235112;
int distance_to_216 = a+1717986918;
if (distance_to_11 > 0) distance_to_11 = -distance_to_11; // -abs
if (distance_to_216 > 0) distance_to_216 = -distance_to_216; // -abs
int nearest;
if ( distance_to_216 > distance_to_11 ) {
nearest = 216;
} else {
nearest = 11;
}
return nearest;
}
The essence of this solution is to map the range [-180° ‒ +180°) to the range of a signed 32-bit integer. Once the mapping is done, one can make use of the natural modulo properties of 2's complement arithmetic.
Note: there is an error introduced in the mapping that will result in incorrect answers for values of a that are increasingly beyond the range of 0‒360. If that is of concern, the value of a should be confined to the range 0‒360.
Note: unlike abs(), the hand-coded -abs ensures a correct result regardless of the input since "The absolute value of the most negative number cannot be represented in two's complement." (see C11 draft).
Derivation of the constants is left as an exercise for the reader.
Here's an alternative 'generic' approach that trades modulo arithmetic and additional compares for some simple trig (instead of separate sin and cos, one could employ sincos if available):
#include <math.h>
int find_point(int a)
{
const double x11 = cos((double)11/180*M_PI);
const double y11 = sin((double)11/180*M_PI);
const double x216 = cos((double)216/180*M_PI);
const double y216 = sin((double)216/180*M_PI);
double x = cos((double)a/180*M_PI);
double y = sin((double)a/180*M_PI);
double square_of_distance_to_11 = (x-x11)*(x-x11) + (y-y11)*(y-y11);
double square_of_distance_to_216 = (x-x216)*(x-x216) + (y-y216)*(y-y216);
int nearest;
if ( square_of_distance_to_216 < square_of_distance_to_11 ) {
nearest = 216;
} else {
nearest = 11;
}
return nearest;
}
The code is reasonably self-explanatory. I'm exploiting the property that finding the nearest two points on a circle using the distance along the circle is equivalent to finding the nearest two point on a circle using the straight line distance between the points.
A bit of modulo and +/- trickery can avoid the use of min or max and eliminate the need to compare against additional alias points:
#include <stdlib.h>
int find_point(int a)
{
a = (a%360+360)%360; // clamp 'a' to 0..359
int distance_to_11 = abs((a-11+180+360)%360-180);
int distance_to_216 = abs((a-216+180+360)%360-180);
int nearest;
if ( distance_to_216 < distance_to_11 ) {
nearest = 216;
} else {
nearest = 11;
}
return nearest;
}
this is alternate solution. split circle into three parts as shown in picture. when the number is in green region answer is 11 directly, when the number is in yellow region compare between 11 and 216 and when the number is in blue region compare between 216 and ((360-number)+11)
int find_point(int a)
{
if(a>=0&&a<=11)
return 11;
else if(a>=11&&a<=216)
{
if((a-11)> (216-a))
return 216;
else
return 11;
}
else if(a>=216&&a<=360)
{
if((a-216)>(360-a+11))
return 11;
else
return 216;
}
else
return 0; //for invalid input
}
#include <stdio.h>
#define min(x,y) ((x)<(y)? (x) : (y))
int circle_dist(int a, int b)
{
a = (a%360+360)%360;
b = (b%360+360)%360;
return min(360-abs(a-b), abs(a-b));
}
int main(void) {
printf("%d (10)\n", circle_dist(10,20));
printf("%d (10)\n", circle_dist(20,10));
printf("%d (20)\n", circle_dist(350,10));
printf("%d (20)\n", circle_dist(10,350));
printf("%d (180)\n", circle_dist(310,130));
printf("%d (180)\n", circle_dist(130,310));
printf("%d (0)\n", circle_dist(1080,360));
printf("%d (0)\n", circle_dist(0,720));
return 0;
}

Minimum cuts on a rectangle to make into squares

I'm trying to solve this problem:
Given an a×b rectangle, your task is to cut it into squares. On each move you can select a rectangle and cut it into two rectangles in such a way that all side lengths remain integers. What is the minimum possible number of moves?
My logic is that the minimum number of cuts means the minimum number of squares; I don't know if it's the correct approach.
I see which side is smaller, Now I know I need to cut bigSide/SmallSide of cuts to have squares of smallSide sides, then I am left with SmallSide and bigSide%smallSide. Then I go on till any side is 0 or both are equal.
#include <iostream>
int main() {
int a, b; std::cin >> a >> b; // sides of the rectangle
int res = 0;
while (a != 0 && b != 0) {
if (a > b) {
if (a % b == 0)
res += a / b - 1;
else
res += a / b;
a = a % b;
} else if (b > a) {
if (b % a == 0)
res += b / a - 1;
else
res += b / a;
b = b % a;
} else {
break;
}
}
std::cout << res;
return 0;
}
When the input is 404 288, my code gives 18, but the right answer is actually 10.
What am I doing wrong?
It seems clear to me that the problem defines each move as cutting a rectangle to two rectangles along the integer lines, and then asks for the minimum number of such cuts. As you can see there is a clear recursive nature in this problem. Once you cut a rectangle to two parts, you can recurse and cut each of them into squares with minimum moves and then sum up the answers. The problem is that the recursion might lead to exponential time complexity which leads us directly do dynamic programming. You have to use memoization to solve it efficiently (worst case time O(a*b*(a+b))) Here is what I'd suggest doing:
#include <iostream>
#include <vector>
using std::vector;
int min_cuts(int a, int b, vector<vector<int> > &mem) {
int min = mem[a][b];
// if already computed, just return the value
if (min > 0)
return min;
// if one side is divisible by the other,
// store min-cuts in 'min'
if (a%b==0)
min= a/b-1;
else if (b%a==0)
min= b/a -1;
// if there's no obvious solution, recurse
else {
// recurse on hight
for (int i=1; i<a/2; i++) {
int m = min_cuts(i,b, mem);
int n = min_cuts(a-i, b, mem);
if (min<0 or m+n+1<min)
min = m + n + 1;
}
// recurse on width
for (int j=1; j<b/2; j++) {
int m = min_cuts(a,j, mem);
int n = min_cuts(a, b-j, mem);
if (min<0 or m+n+1<min)
min = m + n + 1;
}
}
mem[a][b] = min;
return min;
}
int main() {
int a, b; std::cin >> a >> b; // sides of the rectangle
// -1 means the problem is not solved yet,
vector<vector<int> > mem(a+1, vector<int>(b+1, -1));
int res = min_cuts(a,b,mem);
std::cout << res << std::endl;
return 0;
}
The reason the foor loops go up until a/2 and b/2 is that cuting a paper is symmetric: if you cut along vertical line i it is the same as cutting along the line a-i if you flip the paper vertically. This is a little optimization hack that reduces complexity by a factor of 4 overall.
Another little hack is that by knowing that the problem is that if you transpose the paper the result is the same, meaining min_cuts(a,b)=min_cuts(b,a) you can potentially reduce computations by half. But any major further improvement, say a greedy algorithm would take more thinking (if there exists one at all).
The current answer is a good start, especially the suggestions to use memoization or dynamic programming, and potentially efficient enough.
Obviously, all answerers used the first with a sub-par data-structure. Vector-of-Vector has much space and performance overhead, using a (strict) lower triangular matrix stored in an array is much more efficient.
Using the maximum value as sentinel (easier with unsigned) would also reduce complexity.
Finally, let's move to dynamic programming instead of memoization to simplify and get even more efficient:
#include <algorithm>
#include <memory>
#include <utility>
constexpr unsigned min_cuts(unsigned a, unsigned b) {
if (a < b)
std::swap(a, b);
if (a == b || !b)
return 0;
const auto triangle = [](std::size_t n) { return n * (n - 1) / 2; };
const auto p = std::make_unique_for_overwrite<unsigned[]>(triangle(a));
/* const! */ unsigned zero = 0;
const auto f = [&](auto a, auto b) -> auto& {
if (a < b)
std::swap(a, b);
return a == b ? zero : p[triangle(a - 1) + b - 1];
};
for (auto i = 1u; i <= a; ++i) {
for (auto j = 1u; j < i; ++j) {
auto r = -1u;
for (auto k = i / 2; k; --k)
r = std::min(r, f(k, j) + f(i - k, j));
for (auto k = j / 2; k; --k)
r = std::min(r, f(k, i) + f(j - k, i));
f(i, j) = ++r;
}
}
return f(a, b);
}

Find a,b,n so that (a^b)%n=x

Say I choose a value for x that can be between 0 and 2147483647. (Int32.MaxValue)
I am trying to figure out how I can find values for a,b,n so that (a^b)%n=x
I already know that I can use ModPow to verify the values, but I don't know how I can find a fitting a,b and n.
#include <iostream>
/// Calculate (a^b)%n
/// \param a The base
/// \param b The exponent
/// \param n The modulo
/// \return (a^b)%n
int ModPow(int a, int b, int n) {
long long x = 1, y = a;
while (b > 0) {
if (b % 2 == 1) {
x = (x * y) % n; // multiplying with base
}
y = (y * y) % n; // squaring the base
b /= 2;
}
return x % n;
}
int main() {
int x = 1337;
// How to find a,b,n so that (a^b)%n=x
int a = ?;
int b = ?;
int n = ?;
if(x == ModPow(a,b,n))
printf("ok");
return 0;
}
int n = 2147483647
int a = ModPow(x, 9241, n);
int b = 464773;
n = 231 − 1 is a prime number. So due to Fermat's little theorem, xn mod n = x and xn − 1 mod n = 1 (unless x = 0) so x2 n − 1 mod n = x, too. 2 n − 1 = 9241 × 464773. So (x9241 mod n)464773 mod n = x. Note that you need x < n for this to work; x = 2147483647 cannot work if n is a 31 bit (i.e. signed) integer, too.
It took me a while to get here; for a long time I've had this answer messing about with Carmichael numbers and the Carmichael function before I reached this easy solution. See edit history for details.
The modulus operator:
Yields the remainder given by the following expression, where e1 is the first operand and e2 is the second: e1 – (e1 / e2) * e2
Therefor whatever the max value of x is, n must be larger. Since you're validating with n as an int and you're specifying the range: 0 and numeric_limits<int>::max() that must be an exclusive range, and for n to be an int the only possible value it can take is: numeric_limits<int>::max().
With n forced our equation effectively becomes: ab = x.
We'll need to do a check here that x is not 1, if it is b = 0 and a can be anything in our legal range so we can arbitrarily pick a = 2. But baring this:
Our requirements are:
1 < a < x and a is an int
1 < b < x and b is an int
Given x, we can search for a combination of a and b that will fit as follows:
auto a = 0.0;
auto b = 1;
if(x == 1) {
a = 2.0;
b = 0;
} else {
while((a = pow(x, 1.0 / ++b)) > 2.0) {
double dummy;
if(modf(a, &dummy) == 0.0) {
break;
}
}
}
At this point, if a >= 2.0 then there is a valid solution to the problem. Now as you as you are probably well aware, pow is a very expensive function so this will likely take a very long time to execute for larger values of x, I'd personally suggest finding an a and b for every number for which such a pair exists and storing them in a map and doing a lookup on that.
Anyway this is a demonstration of working code:
Live Example

Rounding integer division without logical operators

I want a function
int rounded_division(const int a, const int b) {
return round(1.0 * a/b);
}
So we have, for example,
rounded_division(3, 2) // = 2
rounded_division(2, 2) // = 1
rounded_division(1, 2) // = 1
rounded_division(0, 2) // = 0
rounded_division(-1, 2) // = -1
rounded_division(-2, 2) // = -1
rounded_division(-3, -2) // = 2
Or in code, where a and b are 32 bit signed integers:
int rounded_division(const int a, const int b) {
return ((a < 0) ^ (b < 0)) ? ((a - b / 2) / b) : ((a + b / 2) / b);
}
And here comes the tricky part: How to implement this guy efficiently (not using larger 64 bit values) and without a logical operators such as ?:, &&, ...? Is it possible at all?
The reason why I am wondering of avoiding logical operators, because the processor I have to implement this function for, has no conditional instructions (more about missing conditional instructions on ARM.).
a/b + a%b/(b/2 + b%2) works quite well - not failed in billion+ test cases. It meets all OP's goals: No overflow, no long long, no branching, works over entire range of int when a/b is defined.
No 32-bit dependency. If using C99 or later, no implementation behavior restrictions.
int rounded_division(int a, int b) {
int q = a / b;
int r = a % b;
return q + r/(b/2 + b%2);
}
This works with 2's complement, 1s' complement and sign-magnitude as all operations are math ones.
How about this:
int rounded_division(const int a, const int b) {
return (a + b/2 + b * ((a^b) >> 31))/b;
}
(a ^ b) >> 31 should evaluate to -1 if a and b have different signs and 0 otherwise, assuming int has 32 bits and the leftmost is the sign bit.
EDIT
As pointed out by #chux in his comments this method is wrong due to integer division. This new version evaluates the same as OP's example, but contains a bit more operations.
int rounded_division(const int a, const int b) {
return (a + b * (1 + 2 * ((a^b) >> 31)) / 2)/b;
}
This version still however does not take into account the overflow problem.
What about
...
return ((a + (a*b)/abs(a*b) * b / 2) / b);
}
Without overflow:
...
return ((a + ((a/abs(a))*(b/abs(b))) * b / 2) / b);
}
This is a rough approach that you may use. Using a mask to apply something if the operation a*b < 0.
Please note that I did not test this appropriately.
int function(int a, int b){
int tmp = float(a)/b + 0.5;
int mask = (a*b) >> 31; // shift sign bit to set rest of the bits
return tmp - (1 & mask);//minus one if a*b was < 0
}
The following rounded_division_test1() meets OP's requirement of no branching - if one counts sign(int a), nabs(int a), and cmp_le(int a, int b) as non-branching. See here for ideas of how to do sign() without compare operators. These helper functions could be rolled into rounded_division_test1() without explicit calls.
The code demonstrates the correct functionality and is useful for testing various answers. When a/b is defined, this answer does not overflow.
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
int nabs(int a) {
return (a < 0) * a - (a >= 0) * a;
}
int sign(int a) {
return (a > 0) - (a < 0);
}
int cmp_le(int a, int b) {
return (a <= b);
}
int rounded_division_test1(int a, int b) {
int q = a / b;
int r = a % b;
int flag = cmp_le(nabs(r), (nabs(b) / 2 + nabs(b % 2)));
return q + flag * sign(b) * sign(r);
}
// Alternative that uses long long
int rounded_division_test1LL(int a, int b) {
int c = (a^b)>>31;
return (a + (c*2 + 1)*1LL*b/2)/b;
}
// Reference code
int rounded_division(int a, int b) {
return round(1.0*a/b);
}
int test(int a, int b) {
int q0 = rounded_division(a, b);
//int q1 = function(a,b);
int q1 = rounded_division_test1(a, b);
if (q0 != q1) {
printf("%d %d --> %d %d\n", a, b, q0, q1);
fflush(stdout);
}
return q0 != q1;
}
void tests(void) {
int err = 0;
int const a[] = { INT_MIN, INT_MIN + 1, INT_MIN + 1, -3, -2, -1, 0, 1, 2, 3,
INT_MAX - 1, INT_MAX };
for (unsigned i = 0; i < sizeof a / sizeof a[0]; i++) {
for (unsigned j = 0; j < sizeof a / sizeof a[0]; j++) {
if (a[j] == 0) continue;
if (a[i] == INT_MIN && a[j] == -1) continue;
err += test(a[i], a[j]);
}
}
printf("Err %d\n", err);
}
int main(void) {
tests();
return 0;
}
Let me give my contribution:
What about:
int rounded_division(const int a, const int b) {
return a/b + (2*(a%b))/b;
}
No branch, no logical operators, only mathematical operators. But it could fail if b is great than INT_MAX/2 or less than INT_MIN/2.
But if 64 bits are allowed to compute 32 bits rounds. It will not fail
int rounded_division(const int a, const int b) {
return a/b + (2LL*(a%b))/b;
}
Code that I came up with for use on ARM M0 (no floating point, slow divide).
It only uses one divide instruction and no conditionals, but will overflow if numerator + (denominator/2) > INT_MAX.
Cycle count on ARM M0 = 7 cycles + the divide (M0 has no divide instruction, so it is toolchain dependant).
int32_t Int32_SignOf(int32_t val)
{
return (+1 | (val >> 31)); // if v < 0 then -1, else +1
}
uint32_t Int32_Abs(int32_t val)
{
int32_t tmp = val ^ (val >> 31);
return (tmp - (val >> 31));
// the following code looks like it should be faster, using subexpression elimination
// except on arm a bitshift is free when performed with another operation,
// so it would actually end up being slower
// tmp = val >> 31;
// dst = val ^ (tmp);
// dst -= tmp;
// return dst;
}
int32_t Int32_DivRound(int32_t numerator, int32_t denominator)
{
// use the absolute (unsigned) demominator in the fudge value
// as the divide by 2 then becomes a bitshift
int32_t sign_num = Int32_SignOf(numerator);
uint32_t abs_denom = Int32_Abs(denominator);
return (numerator + sign_num * ((int32_t)(abs_denom / 2u))) / denominator;
}
since the function seems to be symmetric how about sign(a/b)*floor(abs(a/b)+0.5)