Dark Bit Factory & Gravity
PROGRAMMING => C / C++ /C# => Topic started by: va!n on February 11, 2012
-
When having an array filled with values between 0 and 255 and reading its values... i want just only get 0 if the value is 0 or 255 if the value is > 0.
At the moment i do this with a If() condition and save the result into a temp array, because for my needs the If() condition is to CPU expensive (very low machine).
So i thought if there is any way without a temp array and without the need of an If() codition to do the same thing, for creating a mask?
This works... (suprised)
if (iData1[i] > 0)
{
iMask1[i] = 0;
}
else
{
iMask1[i] = 255;
}
while this ends up wrong results for later processing...
if (iData1[i] > 0)
{
iMask1[i] = 255;
}
else
{
iMask1[i] = 0;
}
-
It can be done various ways but it depends on the datatypes of your arrays.
Going by the description of what you want rather than the code.
if imask1[] is ubyte then this might work
imask1[i] = idata1[i] > 0;
if it's an int or uint then you'd need to mask it
imask1[i] = ( idata1[i] > 0 ) & 0xff;
another way for a signed int is
imask1[i] = ( ( -idata1[i] ) >> 31 ) & 0xff;
-
Thanks for your fast replay. I have tried myself something without luck, so i have tried your ideas....
iMask1[i] = iData1[i] > 0;
iMask1[i] = (iData1[i] > 0);
VS2010 C# Error - Can't convert type bool into byte... and writing (byte) == converting costs time too and it still does not works/compile ^^
Btw never saw something like > 0 without an If() codition before... So what happens here exactly?
-
It results in true, -1 (all bits 1) or false, 0 (all bits 0)
It works in FB and I'm sure I've seen it in C++
What data types are you using? and I'll see what else I can think of.
-
i am using C# as language (not sure if there is something different) and i use byte as data type for the array and its values.
public byte[] iData1 = new byte[ 32768 ];
public byte[] iMask1 = new byte[ 32768 ];
-
If it's a signed byte then writing 255 into it will make it -1, a signed byte is in the range -128 to 127
but maybe this will work
imask1[i] = ( - idata1[i] ) >> 7;
although if idata1 is more than 127 (or a value more than 127 has been written to it) then it will be negative and imask1 will be set to 0, this may be why your code seems to be the wrong way round
-
For ubytes in freebasic doing it like this seems to work
imask1[i] = ( - idata1[i] ) >> 8;
but I get the feeling that's not guaranteed to work in C#
I can't think of a way with ubytes atm other than a bit of assembly (this is in FB)
sub main
dim as ubyte idata1(0 to 32767),imask1(0 to 32767)
for i as integer=1 to 20
idata1(i)=rnd*2'255
asm
mov ebx,dword ptr[i] 'load index
cmp byte ptr[idata1+ebx],0 'compare byte in array with 0
setz al 'if byte=0 then al=1 else al=0
dec al 'if al=1 then al=0 else al=255
mov byte ptr[imask1+ebx],al 'store byte to (imask1 array)
end asm
print idata1(i);" ";imask1(i)
next
end sub
main
sleep
-
When having an array filled with values between 0 and 255 and reading its values... i want just only get 0 if the value is 0 or 255 if the value is > 0.
At the moment i do this with a If() condition and save the result into a temp array, because for my needs the If() condition is to CPU expensive (very low machine).
Have you profiled your code and found this to be an actual bottleneck?
With the advent of conditional move (http://www.rcollins.org/p6/opcodes/CMOV.html) and branch-prediction (http://en.wikipedia.org/wiki/Branch_predictor), if-statements are less trouble than they used to be.
Unless, of course, the compare-results are completely random (but with your dispersal of 255:1 that's quite unlikely).
Any CPU that's able to run C# code should support both features and the JIT should be clever enough to use it.
-
-> stonemonkey - it's worth noting that C#'s rules for promoting operands is different than in C and C++ where they are all promoted to the type of the largest operand. In C# all operations are done as int or larger. This means some of the twos-complement tricks work differently. Also, zero integer values and null pointers cannot be used as booleans. You need explicitly to do a compare.
eg.
int a = 0;
if (a) {}
object b = null;
if (b) {}
are both syntax errors.
http://msdn.microsoft.com/en-us/library/aa691330%28v=VS.71%29.aspx (http://msdn.microsoft.com/en-us/library/aa691330%28v=VS.71%29.aspx)
Jim
-
Thanks Jim, I didn't realise there were differences like that although when I was looking at some of the operations on bytes in FB I started to see why there could be.