Company logo
  • Empleos
  • Bootcamp
  • Acerca de nosotros
  • Para profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
    • Bootcamp
  • Para empresas
    • Inicio
    • Nuestro proceso
    • Planes
    • Pruebas
    • Nómina
    • Blog
    • Calculadora

0

84
Vistas
Why does left-shifting an integer by 24-bit yield the wrong result?

I tried left-shifting a 32-bit integer by 24:

char *int_to_bin(int num) {
    int i = 0;
    static char bin[64];
   
    while (num != 0) {
        bin[i] = num % 2 + 48;
        num /= 2;
        i++;
    }
    bin[i] = '\0';
    return (bin);
}

int main() {
    int number = 255;
    printf("number: %s\n", int_to_bin(number));
    printf("shifted number: %s\n", int_to_bin(number << 24));
    return 0;
}

OUTPUT:

number: 11111111
shifted number: 000000000000000000000000/

and i left-shift with 23-bit it yields this result:

0000000000000000000000011111111

Well Why is it like that and what's the matter with '/' at the end of the wrong result?

9 months ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Two things:

  • If number has the value 255 then number << 24 has the numerical value 4278190080, which overflows a 32-bit signed integer whose largest possible value is 2147483647. Signed integer overflow is undefined behavior in C, so the result could be anything at all.

    What probably happens in this case is that the result of the shift is negative. When num is negative then num % 2 may take the value -1, so you store character 47 in the string, which is /.

    Bit shifting math is usually better to do with unsigned types, where overflow is well-defined (it wraps around and bits just shift off the left and vanish) and num % 2 can only be 0 or 1. (Or write num & 1 instead.)

  • Your int_to_bin routine puts the least-significant bits at the beginning of the string (on the left), so the result is backwards from the way people usually write numbers (with the least-significant bits on the right). You may want to rewrite it.

9 months ago · Santiago Trujillo Denunciar

0

Shift works fine, you simply print it from the wrong direction.

char *int_to_bin(char *buff, int num)
{
    unsigned mask = 1U << (CHAR_BIT * sizeof(num) - 1);
    char *wrk = buff;
    for(; mask; mask >>= 1)
    {
        *wrk++ = '0' + !!((unsigned)num & mask);
    }
    *wrk = 0;
    return buff;
}

int main()
{
    char buff[CHAR_BIT * sizeof(int) + 1];
    int number = 255;
    printf("number: %s\n", int_to_bin(buff, number));
    printf("shifted number: %s\n", int_to_bin(buff, number << 24));
    return 0;
}

Shifting signed integers left is OK, but the right shift is implementation-defined. Many systems use arithmetic shift right and the result is not the same as using the bitwise one:

https://godbolt.org/z/e7f3shxd4

9 months ago · Santiago Trujillo Denunciar

0

  1. you are storing numbers backwards
  2. you are using signed int32 while shifting by 23 results needs more than 32 bits to handle that operation ...you should use long long int
  3. signed integer can lead to wrong answers as 1<<31 is -1 which results in bad characters in string finally using unsigned long long int with storing numbers in correct order will produce correct string
  4. you should try re write code on your own before seeing this improved version of your code

#include<stdio.h>
#include<stdlib.h>
char *int_to_bin( unsigned long long   int num) {
    int i = 0;
    static char bin[65];


    while (i != 64) {
        bin[63-i] = num % 2 + 48;
        num /= 2;
        i++;
    }
    bin[64] = '\0';

    return (bin);
}

int main() {
    unsigned long long  int number = 255;
    printf("number 1: %s\n", int_to_bin(number));
    printf("number 2: %s\n", int_to_bin(number << 24));
    return 0;
}

enter image description here

9 months ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar empleo Planes Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2023 PeakU Inc. All Rights Reserved.