I am currently converting some OpenCV code from C++ to Java. I can\'t use JavaCV, as we need the conversion in native Java, not a JNA. At one point in the code, I get the fo
What it basically does is following:
kHit >= kForeground
is an expression of type bool
-(kHit >= kForeground)
converts this bool into an int (based on true==1
and false==0
) and negates it, which results in true==-1
and false==0
.
This is then converted into a uchar
, which results in -1==255
and 0==0
.
It has to be noted that though seeming as using the underlying implementation details of the numbers, all those conversions are guaranteed by the C++ and C standards, as negative unsigned numbers are specified to behave according to twos-complement.
But if Java doesn't support this, you can always replace it by a conditional assignment:
dst[x] = (kHit>=kForeground) ? 255 : 0;
In C++ a boolean expression produces one of two values - 0
or 1
. When you apply the unary minus -
to the result, you get 0
or -1
. When you re-interpret -1
as uchar
, you get 255
.
You can convert this expression to Java with a conditional:
dst[x] = (kHit >= kForeground) ? 255 : 0;
Because of branching, it is not going to be as fast as the original one. There's little you can do about the speed of it, however, as Java lacks abilities to re-interpret boolean values as numerics.
kHit >= kForeground
returns either true
or false
, which in C++ sort of means 1
or 0
. The minus in front transforms this to -1
or 0
. The cast to uchar
((uchar)
) returns 0
for 0
and wraps to 255
for the negative -1
.
Following Konrad's comment, I'm also skeptical this is well defined. It is well defined, but it's still an awful piece of code in terms of readability. :)
The expression (kHit >= kForeground)
yields a boolean that has value true
or false
. When the unary -
is applied, the bool
gets promoted to an int
, and the conversion yields 1
for true
or 0
for false
. After the promotion, the sign is changed into -1
or 0
and then it is converted to uchar
by the outer cast.
Note that the important bit of information is that the unary operator-
is not applied to a boolean, but the boolean is converted to int
and it is then applied. That can be tested with a bit of template magic:
template <typename T, typename U>
struct same_type {
static const bool value = false;
};
template <typename T>
struct same_type<T,T> {
static const bool value = true;
};
template <typename T>
void f( T value ) {
std::cout << "Is int? " << std::boolalpha << same_type<T, int>::value << "\n";
std::cout << "Is bool? " << same_type<T, bool>::value << "\n";
}
int main() {
f(-true);
}
The f
template tests the type of the passed argument against int
and bool
by using the same_type
templates above (trivial enough to understand). If we call the f
template with -true
as argument type deduction will set T
to be the type of the expression -true
. If you run the program, you will see that it prints Is int? true\nIs bool? false
.