• Welcome to Dark Bit Factory & Gravity.
 

C# - Any way to use &-Operator or mask instead using If() condition?

Started by va!n, February 10, 2012

Previous topic - Next topic

0 Members and 0 Guests are viewing this topic.

va!n

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;
                }


- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Stonemonkey

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;

va!n

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?
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Stonemonkey

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.

va!n

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 ];
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won:

Stonemonkey

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

Stonemonkey

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

hellfire

Quote from: va!n on February 10, 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 and branch-prediction, 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.
Challenge Trophies Won:

Jim

-> 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

Jim
Challenge Trophies Won:

Stonemonkey

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.