#### Archived

This topic is now archived and is closed to further replies.

# Auto clamping 'char'?

This topic is 5485 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have this little test code for my projects math lib:
ubyte u;

u = 254;
cout << int(u) << "\n";

u++;
cout << int(u) << "\n";

u++;
cout << int(u) << "\n";

u++;
cout << int(u) << "\n";

ubyte is just typedef''d as unsigned char. The output is ofcourse "254", "255", "0", "1". However, i''d like to have it output "254", "255", "255", "255" instead. I want clamping. Can this easily be done? Or will I need if() statements? Sander Maréchal

##### Share on other sites
You need to use if statements

##### Share on other sites
class ubyte{  explicit ubyte(unsigned char v) : v_(v) {}  ubyte(int v)   (     if(v > 255)       v_ = 255;    else if(v < 0)      v_ = 0;    else      v_ = v;  }  ubyte() : v_(0) {}  ubyte& operator=(unsigned char v)  {    v_ = v;  }  ubyte& operator=(int v)  (     if(v > 255)       v_ = 255;    else if(v < 0)      v_ = 0;    else      v_ = v;  }  ubyte& operator++()  {    if(v_ = 255)      return *this;    ++v_;    return *this;  }  ubyte& operator++(int)  {    ubyte t = *this;    ++(*this);    return t;  }  //same thing for decrement...  //so we can use it like an unsigned char  unsigned char operator unsigned char() const  { return v_; }private:  unsigned char v_;};

##### Share on other sites
There''s an MMX instruction that''ll do what you want: check out paddusb.

Thanks all

Sander Maréchal

##### Share on other sites
Conditions and chars ... your CPU won''t like it.

Sander it''s possible to simulate MMX stuff with classical integer arithmetic and logical ops without any if(). I did it in the past ... before the MMX existed. I remember crazy asm code that could for instance compute the absolute manhattan distance between two RGB pixels. 9 cycles if I remember well. This was useful to speedup 16bits -> 256 colors textures.

Now here is how you can simulate RGB addition a=b+c with clamping. The trick is you need to detect carry propagation.

uint32 a,b=?,c=?;
uint32 d;

d = b ^ c; // xor, bitwise addition
a = b + c; // addition, carries propagate.
d^= a; // detect differences, that is where carry bits have been added
d&=0x01010100UL; // keep only the carry bits at position 8,16,24
a -=d; // Substract the carries that propagated between components.
e = d>>7UL; // shift so that 256 becomes 1
d-=e; // ex : 0x01000100L gives the mask 0x00FF00FFL
a!=d; // Mask the components which is actually unsigned clamping.

There are many other possible ways to do it ... but equivalently boring. You can greatly speed up things if one of the operands is known to have only components between 0 and 127, that is bit 7,15,23 unset.

Note that to handle RGBA you need "33 bits". In fact you would need the a sbb ecx,ecx to get the last carry bit. This can''t be done easilly in C. The asm code can only be efficient by processing at least two RGBA in //, thus like MMX. A rough count would tell me it''s around 5-8 cycles for 64 bits. Thus much slower than MMX ... of course but also much better than if(r>255) etc ...

So I am not sure it''s worth the challenge simulating such vector byte SIMD since any modern machine has MMX or the equivalent.

##### Share on other sites
Well if I replied about it, though it''s deprecated it''s to show that particularilly today with MMX/3DNow or SSE/SSE2 it''s possible to create some very original and impressive computations for someone experienced with hacks that combine arithmetic/logical operations/floating point format hacks. What''s very interesting with SIMD is you can consider the float, byte or int representations of the same 64 or 128 bits without any or much time lost to convert or cast.

Cf my AABox/Plane computation with 3DNow Sander. It''s done in 9 instructions. AABox/Frustrum can thus be done in 6-30 cycles, roughly 100 million per sec, 1 million per frame at 100FPS

Note that an order of magnitude of 1 million collision checks per frame between AABoxes and Convex Hulls may give some ideas for collision detection ... Do you want one million cube particles colliding on the screen ? Use quasi linear time space partition, then ...

##### Share on other sites
You can also do it with a oneliner like this

a = (a < 0) ? 0 : (a < 256) ? a : 255);

##### Share on other sites
quote:
Original post by Aldacron
You can also do it with a oneliner like this

a = (a < 0) ? 0 : (a < 256) ? a : 255);

I assume you mean

a = (a < 0) ? 0 : (a < 256) ? a + 1: 255);

##### Share on other sites
quote:
Original post by rileyriley
I assume you mean

a = (a < 0) ? 0 : (a < 256) ? a + 1: 255);

Or even:
a = (a < 255) ? a + 1: 255;

It''s an unsigned char; it can''t be less than 0. And incrementing it when it''s equal to 255 will make it wrap.

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 13
• 26
• 10
• 11
• 9
• ### Forum Statistics

• Total Topics
633736
• Total Posts
3013600
×