How to round bytes to 0 or 255 using shift operators

To repeat the pixels in a bitmap in my C # project, I want to round my RGB values ​​to 255 or to 0;

Each value is a byte.

Now I am doing the following:

(byte)(Pixels[i] < 128 ? 0 : 255);

I am sure that this can be achieved in a faster way and without type casting using bitwise operations. How can i do this?

+4
source share
3 answers
   (byte)(Pixels[i] < 128 ? 0 : 255)

Yes, this tends to work poorly due to poor branch prediction if the bitmap contains too much random data. Jitter does not generate a conditional move for such a statement.

, . :

   (byte)((sbyte)Pixels[i] >> 7)

:

000000a7  movsx       eax,byte ptr [edx+eax+8]  ; Pixels[i], sign extended to 32-bits
000000ac  sar         eax,7                     ; >> operator
000000af  and         eax,0FFh                  ; (byte) cast
+7

:

  • (byte)((b << 24) >> 31);
  • (byte)((sbyte)b >> 31);
  • (uint)(int)(sbyte)b >> 24;

, , , -1 0 , , .

, movsx eax,... shr eax, 24 . , .NET JITter .

.

+5

, ( ) .

var lookup = Enumerable.Range(0, 256).Select(i => i < 128 ? (byte)0 : 255).ToArray();

Since you have only 256 values, this can be in the L1 cache, which means that its access is not more expensive than arithmetic calculation:

Pixels[i] = lookup[Pixels[i]];
+3
source

Source: https://habr.com/ru/post/1545487/


All Articles