HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppCritical

Fastest way to clamp an integer to the range 0-255

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
therangeway255fastestintegerclamp

Problem

I'm working on some image processing code that can generate pixel values outside of the normal range of 0 to 255, and I'd like to clamp them back into the valid range. I know that there are saturating SIMD instructions that make this a moot point, but I'm trying to stay within standard C++ code for the moment.

The fastest I've been able to do on my Athlon II is the following:

inline
BYTE Clamp(int n)
{
    n &= -(n >= 0);
    return n | ((255 - n) >> 31);
}


This compiles down into the following assembly with MSVC 6.0:

setns dl
neg   edx
and   eax, edx
mov   edx, 255
sub   edx, eax
sar   edx, 31
or    dl, al


Is there any improvement possible?

Solution

Try

int x=n>255?255:n;
 ... x<0?0:x ...


I'd expect this to produce something like:

mov     ebx, 255
 mov     eax, n
 cmp     eax, ebx
 cmovg   eax, ebx ; conditional mov instruction
 test    eax, eax
 mov     ebx, 0
 cmovl   eax, ebx


If you are using MSVC SIX, you may not get the conditional move instruction. Try switching to a modern version of visual studio.

Code Snippets

int x=n>255?255:n;
 ... x<0?0:x ...
mov     ebx, 255
 mov     eax, n
 cmp     eax, ebx
 cmovg   eax, ebx ; conditional mov instruction
 test    eax, eax
 mov     ebx, 0
 cmovl   eax, ebx

Context

StackExchange Code Review Q#6502, answer score: 57

Revisions (0)

No revisions yet.