Asuntos Oficiales > Retos

 Bitwise Operations

<< < (4/5) > >>

sés:

--- Cita de: "JuanK" --- el >= no es una resta ya que el compilador lo convierte en un JB o en un JNAE segun sea mas conveniente, esta instruccion se realiza en un solo ciclo de procesamiento cosa que en una resta se haria en dos ciclos usando posiblemente SUB y una instruccion de transferencia como JA JB o las otras...
--- Fin de la cita ---
Efectivamente, antes del salto condicional tiene que ir algo, en este caso concreto un CMP o un TEST, que lo que hacen es una RESTA.

Amilius en su solución en ensamblador no usa CMP, usa XOR precisamente por esto.

Además:

--- Cita de: "Noel Solw" ---Problema a solucionar por medio de operaciones con bits : (&,|,^,~,>>,<<)
--- Fin de la cita ---
Se supone que esos son los únicos operadores permitidos, ¿no?

JuanK:
Hola ses..
he revisado mis apuntes y esto es lo ue tengo,
en efecto el >= se convierte habitualmente en un

CMP eax, xxxxx
JG   xxxxxx

Pero el CMP no es una resta si fuese una resta seria :
SUB xxxxxxo
SBB xxxxxx
CMPxxxx xxx
JG  xxxxx

Realmente no creo que la instruccion CMP use internamente una resta porque seria muy lento me late que debe hacer un XORo alguna de esas si es posible buscare documentacion al respecto aunque realmente no sipongo de mucho tiempo puesto que al dedicarme al famoso ciadrado magico he descuidado un poco lo de mi tesis de grado  y tengo que compensar el tiempo.

sés:
En mi viejo libro de ensamblador para el 386 dicen textualmente que CMP realiza una resta sin almacenar el resultado. Para SUB y CMP indican los mismo ciclos de reloj (por cierto, que CMP viene en la sección de ARITMÉTICAS).

Un vistazo a GameDev.net - Intel 80386 Programmer's Reference Manual verifica esto mismo:


--- Citar ---Description

CMP subtracts the second operand from the first but, unlike the SUB instruction, does not store the result; only the flags are changed. CMP is typically used in conjunction with conditional jumps and the SETcc instruction. (Refer to Appendix D for the list of signed and unsigned flag tests provided.) If an operand greater than one byte is compared to an immediate byte, the byte value is first sign-extended.
--- Fin de la cita ---

Y esto lo pone varias veces:

--- Citar ---...(subtraction instructions SUB, SBB, DEC, AAS, DAS, CMP, and NEG)...
--- Fin de la cita ---

JuanK:
Orale, eso si es lo que necesitabamos.. entonces CMP hace una resta sin almacenar resultados... vaya vaya vaya ;)

gracias  :smartass:

carlos20:
Hola sés
 Intente resolver este incidente por otras vías pero no fue posible y me veo en la obligación de responderte .


--- Citar ---2º No sé si eres bueno... pero lo que tengas de bueno te falta en educación. No sé a qué viene dudar de mí nada más llegar, pero bueno... ya he visto otros mensajes tuyos en el foro y veo que la educación no es tu fuerte *mira a Nagisa*... simplemente te ignoraré.

--- Fin de la cita ---

Sés después de ese comentario queda demostrado que la educación tampoco es tu fuerte , no se porque te molestaste tanto por lo que dije pero como veo que lo interpretaste mal  te lo explicare lo extraño en tu mensaje es que el programa falla , y me parece extraño que en el primer mensaje de un usuario en un foro sea para reabrir una discusión cerrada hace varios meses para enviar un programa que falla , no te lo dije en mi mensaje anterior porque creí que al decirte que el mensaje tenia algo extraño notarias el error en el programa o porque tal vez el error en el programa fue un error de redacción cuando lo escribiste en tu mensaje , pero mi comentario se presto para un mal entendido y fue por esa razón que lo modifique el mismo día .



--- Código: Text --- //compilado en visual c++#include &#60;iostream&#62;#include &#60;math.h&#62; using namespace std; //es la misma funcionint checkOverflow( unsigned n1, unsigned n2 ){  int mask = 0x80;    while( mask & ((n1 & mask) ^ (n2 & mask)) ) {    mask &#62;&#62;= 1;    mask &= 0x7fffffff;  }    return mask & (n1 & mask) & (n2 & mask);} int main(){  unsigned A = 0xFFFFFFFF;    unsigned B = 0;      int b;      for(unsigned n=8&#59; n&#60;32&#59; n++){    B = pow(2,n);        b = checkOverflow(A,B);      if(b)       cout&#60;&#60;&#34;SI : &#34;&#60;&#60;n&#60;&#60;endl;      else       cout&#60;&#60;&#34;NO : &#34;&#60;&#60;n&#60;&#60;endl;  }    cin.get();   A = 0x7fffffff;  B = 0;  for(n=0&#59; n&#60;1000&#59; n++){        b = checkOverflow(A,B);    B++;      if(b)       cout&#60;&#60;&#34;SI : &#34;&#60;&#60;n&#60;&#60;endl;      else       cout&#60;&#60;&#34;NO : &#34;&#60;&#60;n&#60;&#60;endl;  }    return 1;}  

sés Escrito el 23/03/2005, 03:38 PM

--- Código: Text --- int checkOverflow( unsigned n1, unsigned n2 ){  int mask = 0x80;    while( mask & ((n1 & mask) ^ (n2 & mask)) ) {    mask &#62;&#62;= 1;    mask &= 0x7fffffff;  }    return mask & (n1 & mask) & (n2 & mask);}  

--- Citar ---Esta función devuelve verdadero si hay desbordamiento al sumar los números.
Es para enteros de 4 bytes, pero es fácil modificarlo para otros tamaños.

--- Fin de la cita ---

La función tal como esta en tu mensaje no detecta el desborde en todos los casos y falla al menos en los casos que demuestro en este programa , estoy asumiendo que la función debe retornar verdadero cuando hay desborde como lo dices en el mensaje , para desbordar un entero sin signo de 4 bytes  es necesario un valor mayor a 0xffffffff pero si paso como argumento a la función 0xffffffff y 0x80000000 la función retorna falso ¿quiere decir que no hay overflow al sumar 0xffffffff y 0x80000000 ? el overflow es mas que evidente en este caso y en los casos que prueva el programa y la función dice que no hay overflow ,si le paso a la función 0x7fffffff y 1 por ejemplo la función retorna verdadero ¿ por que? si la suma de 0x7fffffff y 1 para enteros de 4 bytes sin signo no genera un overflow . otra cosa es que la operación mask &= 0x7fffffff no tiene ningún efecto en el valor de mask  porque en la función le asignas a mask 128 (10000000 en binario ) y luego divides entre 2 ( >>1 que es equivalente ) el 128 en algunos casos 7 veces 64 , 32 , 16 , 8 , 4 , 2 , 1  y en ocasiones 8 veces  hasta que el valor de mask es 0 ( la división entera de 1/2 ) el valor 0x7fffffff permanece constante y realizar la operación & entre 0x7fffffff y los números 64 , 32 , 16 , 8 , 4 , 2 , 1 y 0 da como resultado los mismos números .


--- Citar ---3º Tu método usa una comparación, lo que significa que hace una resta. Eso me da que no sería válido para el reto.

--- Fin de la cita ---
   

Bueno si mi programa no es valido porque genera instrucciones  equivalentes a una resta tu programa tampoco seria valido porque la operación >>1 es equivalente a dividir entre 2 no estoy diciendo que genera las mismas instrucciones en ensamblador estoy diciendo que mask >>= 1 es equivalente a mask /=2 ; en el programa que fue enviado antes por nagisa como solución a este reto se uso el operador != y aun así fue considerado como valido .

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior

Ir a la versión completa