How about std::max
?
int value = 5;
for (int x=0; x<100; x++) {
cout << value << " ";
value = std::max(0, --value);
}
Вопрос
In programming, modulus is useful to keep numbers in range not exceeding an upper bound limit.
For example:
int value = 0;
for (int x=0; x<100; x++)
cout << value++%8 << " "; //Keeps number in range 0-7
Output:
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7...
Now consider this situation:
int value = 5;
for (int x=0; x<100; x++)
cout << value-- << " ";
Output: 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7...
My question is: How to set the lower bound limit to 0 WITHOUT using any conditional statement like if or switch case?
Output I want: 5 4 3 2 1 0 0 0 0 0 0 0 ...
Решение
How about std::max
?
int value = 5;
for (int x=0; x<100; x++) {
cout << value << " ";
value = std::max(0, --value);
}
Другие советы
Use std::max(value,0)
or the ternary operator. Both will compile to code without conditional jumps.
Perhaps it can be done with
typedef unsigned u32b;
u32b sat_subu32b(u32b x, u32b y)
{
u32b res = x - y;
res &= -(res <= x);
return res;
}
which is taken from here. More specifically it seems to implement saturated subtraction; the saturated decrement would be
u32b sat_dec(u32bx)
{
u32b res = x-1;
res &= -(res <= x);
return res;
}
and seems to be branch-free.
The two situations are different. As you've shown, the %
will make the numbers loop around from 0
to 7
, whereas in the negative case you seem to be asking for the max
.
Depending on whether you count the ternary operator as a conditional, you could do:
int value = 5;
for (int x=0; x<100; x++)
cout << value > 0 ? value-- : 0 << " ";
This has the side effect that value
will no longer be decremented once it has reached 0
.
Alternatively, you could use a std::max
:
int value = 5;
for (int x=0; x<100; x++)
cout << std::max(0, value--) << " ";
using max
function in std
.
max
function detail:
template <class T> const T& max (const T& a, const T& b) {
return (a<b)?b:a;
}