Para problemas futuros como este, la página bit hack puede ser útil: http://graphics.stanford.edu/~seander/bithacks.html.
Desde el bithack de mínimo y máximo ya fue publicada, aquí es diferente:
// CHAR_BIT is number of bits per byte.
// sign = 1 if x < 0, sign = 0 otherwise (according to the page above)
int sign = (int)((unsigned int)((int)x) >> (sizeof(int) * CHAR_BIT - 1));
int y = (1-sign)*x; // if x < 0, then y = 0, else y = x.
// Depending on arch, the below _might_ cause a branch.
// (on x64 it does not cause a branch, not sure about MIPS)
int z = !(y/some_maximum); // if 0 <= y < some_maximum, z = 1, else z = 0
int ret = z*y + (1-z)*some_maximum; // if z =1, then ret = y; else ret = some_maximum.
return ret;
yo sólo probé y funcionó para los pocos casos de prueba que tenía.
Aquí está el código de ensamblaje de mi computadora (intel arch) que no muestra ramas.
int cap(int x)
{
00F013A0 push ebp
00F013A1 mov ebp,esp
00F013A3 sub esp,0FCh
00F013A9 push ebx
00F013AA push esi
00F013AB push edi
00F013AC lea edi,[ebp-0FCh]
00F013B2 mov ecx,3Fh
00F013B7 mov eax,0CCCCCCCCh
00F013BC rep stos dword ptr es:[edi]
int some_maximum = 100;
00F013BE mov dword ptr [some_maximum],64h
// CHAR_BIT is number of bits per byte.
// sign = 1 if x < 0, sign = 0 otherwise (according to the page above)
int sign = (int)((unsigned int)((int)x) >> (sizeof(int) * CHAR_BIT - 1));
00F013C5 mov eax,dword ptr [x]
00F013C8 shr eax,1Fh
00F013CB mov dword ptr [sign],eax
int y = (1-sign)*x; // if x < 0, then y = 0, else y = x.
00F013CE mov eax,1
00F013D3 sub eax,dword ptr [sign]
00F013D6 imul eax,dword ptr [x]
00F013DA mov dword ptr [y],eax
// Depending on arch, the below _might_ cause a branch.
// (on x64 it does not cause a branch, not sure about MIPS)
int z = !(y/some_maximum); // if 0 <= y < some_maximum, z = 1, else z = 0
00F013DD mov eax,dword ptr [y]
00F013E0 cdq
00F013E1 idiv eax,dword ptr [some_maximum]
00F013E4 neg eax
00F013E6 sbb eax,eax
00F013E8 add eax,1
00F013EB mov dword ptr [z],eax
int ret = z*y + (1-z)*some_maximum; // if z =1, then ret = y; else ret = some_maximum.
00F013EE mov eax,dword ptr [z]
00F013F1 imul eax,dword ptr [y]
00F013F5 mov ecx,1
00F013FA sub ecx,dword ptr [z]
00F013FD imul ecx,dword ptr [some_maximum]
00F01401 add eax,ecx
00F01403 mov dword ptr [ret],eax
return ret;
00F01406 mov eax,dword ptr [ret]
}
00F01409 pop edi
00F0140A pop esi
00F0140B pop ebx
00F0140C mov esp,ebp
00F0140E pop ebp
00F0140F ret
Creo que bastante obviamente significa "sin ramificaciones en el ejecutable", no "sin el uso de' if' declaraciones" –
No resulta obvio, el término se utiliza en más de un contexto. Bueno, me complace eliminar mi respuesta si se aclara. –
Solo una nota, si esto es para producción, lo que tienes es casi tan bueno como obtendrás, especialmente en términos de legibilidad (que generalmente es mucho más importante que algunas instrucciones de la CPU). Por supuesto, si la pregunta es para más propósitos de curiosidad, entonces parece mucho más relevante. Después de todo, los científicos informáticos son los reyes de "¿Por qué lo hiciste de esa manera?" "¡Porque podemos!" – corsiKa