Dark Bit Factory & Gravity

PROGRAMMING => C / C++ /C# => Topic started by: va!n on February 11, 2012

Title: C# - Any way to use &-Operator or mask instead using If() condition?
Post 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?


Code: [Select]
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;
                }

Title: Re: Any way to use &-Operator or mask instead using If() condition?
Post by: Stonemonkey on February 11, 2012
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
Code: [Select]
imask1[i] = idata1[i] > 0;
if it's an int or uint then you'd need to mask it
Code: [Select]
imask1[i] = ( idata1[i] > 0 ) & 0xff;
another way for a signed int is
Code: [Select]
imask1[i] = ( ( -idata1[i] ) >> 31 ) & 0xff;
Title: Re: Any way to use &-Operator or mask instead using If() condition?
Post by: va!n on February 11, 2012
Thanks for your fast replay. I have tried myself something without luck, so i have tried your ideas....

Code: [Select]
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?
Title: Re: Any way to use &-Operator or mask instead using If() condition?
Post by: Stonemonkey on February 11, 2012
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.
Title: Re: Any way to use &-Operator or mask instead using If() condition?
Post by: va!n on February 11, 2012
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 ];
Title: Re: C# - Any way to use &-Operator or mask instead using If() condition?
Post by: Stonemonkey on February 11, 2012
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

Code: [Select]
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
Title: Re: C# - Any way to use &-Operator or mask instead using If() condition?
Post by: Stonemonkey on February 11, 2012
For ubytes in freebasic doing it like this seems to work
Code: [Select]
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)
Code: [Select]

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
Title: Re: C# - Any way to use &-Operator or mask instead using If() condition?
Post by: hellfire on February 12, 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).
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.
Title: Re: C# - Any way to use &-Operator or mask instead using If() condition?
Post by: Jim on February 13, 2012
-> 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.
Code: [Select]
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
Title: Re: C# - Any way to use &-Operator or mask instead using If() condition?
Post by: Stonemonkey on February 13, 2012
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.