elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  [Solucionado][Consulta / Duda] Desplazando más de 31 bits
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [Solucionado][Consulta / Duda] Desplazando más de 31 bits  (Leído 4,031 veces)
BloodSharp


Desconectado Desconectado

Mensajes: 811


¡ Hiperfoco !


Ver Perfil WWW
[Solucionado][Consulta / Duda] Desplazando más de 31 bits
« en: 14 Marzo 2021, 06:51 am »

Primero antes que nada buenos días/noches.

Bueno digamos que estaba muy aburrido :xD y me puse a generar un código que sume en Complemento a 2:

Código
  1. #include <cstdio>
  2. #include <cstdint>
  3.  
  4. int64_t SumadorCompleto(int64_t A,int64_t B,uint8_t TamanioBits=(sizeof(int64_t)*8))
  5. {
  6.    int64_t Resultado;
  7.    int64_t PrimeraOp;
  8.    int64_t SegundaOp;
  9.    int64_t i;
  10.    int64_t CarryActual;
  11.    CarryActual^=CarryActual;
  12.    Resultado^=Resultado;
  13.    for(i^=i;i<TamanioBits;i++)
  14.    {
  15.        PrimeraOp=((A>>i)&1)^((B>>i)&1);
  16.        SegundaOp=(PrimeraOp&1)^(CarryActual&1);
  17.        Resultado|=(SegundaOp<<i)&(1<<i);
  18.        CarryActual=(PrimeraOp&1)&&(CarryActual&1)||((((A>>i)&1)&&((B>>i)&1))&1);
  19.    }
  20.    return Resultado;
  21. }
  22.  
  23. int main()
  24. {
  25.    int64_t A=4,B=-7;
  26.    printf("A:%li + B:%li = %li\n",A,B,SumadorCompleto(A,B));
  27.    return 0;
  28. }

Si lo pruebo con ambos números enteros pequeños 4 y 7 el código funciona perfectamente, ahora el problema es cuando pongo un número entero gigante o negativo el código no funciona:



Dije quizás sea un error de GCC voy a probar otro compilador diferente y de diferente lenguaje como Pascal:

(No puedo subir el código en Pascal porque el foro no lo permite)

(Solución temporal o hasta que alguien lo verifique lo subo en imagenes)




Lo cuál ocurre lo mismo:



Pero lo que me inquietó es que pasado los 31 bits de desplazamiento no parece realizar operaciones al menos de manera correcta:



Mi duda es hay alguna manera de llegar a desplazar más bits correctamente, o yo tengo algún error y no me dí cuenta todavía del error o ¿También es una limitación de los procesadores esto?


B#


« Última modificación: 14 Marzo 2021, 23:21 pm por BloodSharp » En línea



Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.958


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: [Consulta / Duda] Desplazando más de 31 bits
« Respuesta #1 en: 14 Marzo 2021, 10:30 am »

Desplazar no es un problema:
Código
  1. for (int x = 0; x < 64; ++x)
  2.    printf("%d 0x%.I64X\r\n", x, (int64_t)1 << x);

https://en.wikipedia.org/wiki/Two%27s_complement#Addition


En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: [Consulta / Duda] Desplazando más de 31 bits
« Respuesta #2 en: 14 Marzo 2021, 12:20 pm »

Me gustó tu ejercicio. Aquí una solución mía:

Código
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <stdint.h>
  4.  
  5. uint64_t complemento_a_2(uint64_t num) {
  6.    return (num ^ -1) + 1;
  7. }
  8.  
  9. /**
  10.  * Devuelve el valor de una resta realizada con
  11.  * complemento a dos en forma humana. Los operandos deben
  12.  * ser positivos por trabajar a nivel de bits
  13.  * a: minuendo
  14.  * b: sustraendo
  15.  * c: puntero a la variable que contendrá el resultado
  16.  * retorna: true si el resultado es negativo; false si es positivo
  17.  */
  18. bool resta(uint64_t a, uint64_t b, uint64_t *resultado) {
  19.    bool signo;
  20.  
  21.    *resultado = a + complemento_a_2(b);
  22.    signo = *resultado >> (sizeof(uint64_t) * 8 - 1);
  23.    if(signo) {
  24.        *resultado = complemento_a_2(*resultado);
  25.    }
  26.  
  27.    return signo;
  28. }
  29.  
  30. int main() {
  31.    uint64_t a = 3, b = 7, resultado;
  32.  
  33.    if(resta(a, b, &resultado)) {
  34.        putchar('-');
  35.    }
  36.    printf("%I64u\n", resultado);
  37. }
  38.  
En línea

BloodSharp


Desconectado Desconectado

Mensajes: 811


¡ Hiperfoco !


Ver Perfil WWW
Re: [Consulta / Duda] Desplazando más de 31 bits
« Respuesta #3 en: 14 Marzo 2021, 16:47 pm »

Gracias a ambos por responder, he cambiado el código para realizar el mismo problema con operaciones de 32 bits y si funciona perfectamente:

Código
  1. #include <cstdio>
  2. #include <cstdint>
  3.  
  4. int32_t SumadorCompleto(int32_t A,int32_t B,int8_t TamanioBits=(sizeof(int32_t)*8))
  5. {
  6.    int32_t Resultado;
  7.    int32_t PrimeraOp;
  8.    int32_t SegundaOp;
  9.    int32_t i;
  10.    int8_t CarryActual;
  11.    CarryActual^=CarryActual;
  12.    Resultado^=Resultado;
  13.    for(i^=i;i<TamanioBits;i++)
  14.    {
  15.        PrimeraOp=((A>>i)&1)^((B>>i)&1);
  16.        SegundaOp=(PrimeraOp&1)^(CarryActual&1);
  17.        Resultado|=(SegundaOp<<i)&(1<<i);
  18.        CarryActual=(PrimeraOp&1)&&(CarryActual&1)||((((A>>i)&1)&&((B>>i)&1))&1);
  19.    }
  20.    return Resultado;
  21. }
  22.  
  23. int main()
  24. {
  25.    int32_t A=4,B=-7;
  26.    printf("A:%i + B:%i = %i\n",A,B,SumadorCompleto(A,B));
  27.    return 0;
  28. }



Me doy por vencido :xD espero no necesitar números con 64 bits en mis proyectos reales...


B#
En línea



RayR

Desconectado Desconectado

Mensajes: 243


Ver Perfil
Re: [Consulta / Duda] Desplazando más de 31 bits
« Respuesta #4 en: 14 Marzo 2021, 20:04 pm »

El problema con 64 bits pasa porque esta expresión:

Código
  1. (1<<i)

tiene el tipo del operando izquierdo (la constante literal 1), o sea int. En otras palabras, en realidad estás efectuando el desplazamiento sobre un valor de 32 bits. Si conviertes ese 1 a int64_t, debería funcionar.
« Última modificación: 14 Marzo 2021, 20:11 pm por RayR » En línea

BloodSharp


Desconectado Desconectado

Mensajes: 811


¡ Hiperfoco !


Ver Perfil WWW
Re: [Solucionado][Consulta / Duda] Desplazando más de 31 bits
« Respuesta #5 en: 14 Marzo 2021, 23:21 pm »

El problema con 64 bits pasa porque esta expresión:

Código
  1. (1<<i)

tiene el tipo del operando izquierdo (la constante literal 1), o sea int. En otras palabras, en realidad estás efectuando el desplazamiento sobre un valor de 32 bits. Si conviertes ese 1 a int64_t, debería funcionar.

Si era eso gracias, tema solucionado. ;-) ;-)


B#
En línea



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Duda en conversion de 24 bits a 32 bits
Programación C/C++
armizh 6 4,019 Último mensaje 23 Enero 2012, 07:03 am
por BlackZeroX
Operadores con bits - consulta
Programación C/C++
HRSLASH 4 2,780 Último mensaje 6 Noviembre 2012, 17:16 pm
por HRSLASH
consulta sobre ubuntu para 64 bits
GNU/Linux
xkiz ™ 5 4,389 Último mensaje 11 Junio 2013, 17:12 pm
por xkiz ™
(Consulta) ¿Por qué un procesador de 32 bits solo soporta 2 GB de RAM?
Java
Seyro97 4 2,330 Último mensaje 7 Agosto 2015, 02:53 am
por Seyro97
[Consulta] Operador OR para operaciones lógicas de bits en Lua 5.1.5
Scripting
BloodSharp 0 2,158 Último mensaje 25 Junio 2020, 18:17 pm
por BloodSharp
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines