Author Topic: C# - Any way to use &-Operator or mask instead using If() condition?  (Read 5854 times)

0 Members and 1 Guest are viewing this topic.

Offline va!n

  • Pentium
  • *****
  • Posts: 1432
  • Karma: 109
    • View Profile
    • http://www.secretly.de
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;
                }

« Last Edit: February 11, 2012 by va!n »
- 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:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
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;
« Last Edit: February 11, 2012 by Stonemonkey »

Offline va!n

  • Pentium
  • *****
  • Posts: 1432
  • Karma: 109
    • View Profile
    • http://www.secretly.de
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?
- 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:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
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.
« Last Edit: February 11, 2012 by Stonemonkey »

Offline va!n

  • Pentium
  • *****
  • Posts: 1432
  • Karma: 109
    • View Profile
    • http://www.secretly.de
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:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
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
« Last Edit: February 11, 2012 by Stonemonkey »

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
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
« Last Edit: February 11, 2012 by Stonemonkey »

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
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.
« Last Edit: February 12, 2012 by hellfire »
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
-> 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

Jim
« Last Edit: February 13, 2012 by Jim »
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
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.