Publi

Bailando con bits III. Mostrando el valor binario de un número [bash, C, C++, PHP, Java, Python, Ruby]

photo-1425036458755-dc303a604201_red

De todos es sabido que un ordenador, internamente trabaja con ceros y unos, simplemente eso, a partir de ese simple valor, verdadero o falso, abierto o cerrado, existe o no existe es capaz de formar sonidos, imágenes, textos y cualquier cosa que podamos imaginarnos.

Aunque no vamos a hacer algo tan complicado, muchas veces puede que tengamos un valor entre manos y queramos saber qué bits hay a uno y qué bits hay a cero aunque sólo sea para verificar que una operación se está realizando como debe o porque estamos aprendiendo a utilizar este sistema de numeración y queremos verificar que todo nos sale bien.

En este post, voy a poner algunos métodos que podemos utilizar en varios lenguajes de programación, o en consola, con este propósito.

Decimal a binario en consola

Empecemos en consola. Vamos a utilizar dos formas, una utilizando perl (en realidad nos valdría cualquier lenguaje en el que podamos hacer un script, como awk; aunque en perl lo he visto muy sencillo):

1
2
$ echo 'printf("%b", 12)' | perl
1100

Pocas implementaciones de printf incluyen %b para mostrar un número en base2, pero en perl podemos usar números de hasta 18446744073709551615 (64 bits), sin problema. Podríamos recoger el número en una variable así:

1
2
$ numero=15; echo 'printf("%b", '$numero')' | perl
1111

Parece que hacemos algo raro con las comillas, y es que $numero será una variable de nuestro interprete de consola (en mi caso Bash) y no de perl. Otra opción que tenemos es:

1
2
$ numero=128; echo "printf('%b', $numero)" | perl
10000000

Podemos hacerlo como queramos.

Otra opción es utilizar el programa bc, en el que no tendremos en principio restricción del número de bits, todo puede ser que tu ordenador se tire media hora calculando bits, pero él puede con lo que le eches:

1
2
$ echo "obase=2; 1234" | bc
10011010010

O si lo preferimos con una variable:

1
2
$ numero=170; echo "obase=2;$numero" | bc
10101010

Lo importante aquí es obase en el que decimos la base que queremos como salida de las operaciones de bc. En realidad con bc podemos hacer muchas más cosas (sumas, restas, multiplicaciones, divisiones, raíces, senos, cosenos, logaritmos, incluso sencillos programas de lógica.

C

Vale, mi lenguaje favorito, lo dejo para el segundo. Es verdad que en algunas implementaciones de la biblioteca estándar de C, la función printf incluye un indicador de formato %b (para binario, como el ejemplo de perl de antes), pero no es lo normal. Así que si queremos sacar el valor en binario de un número, tendremos que hacerlo a mano, para ello, tengo aquí una función a mano (podemos meterla en un archivo sacabits.h e incluirlo en nuestro proyecto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#ifndef _SACABITS_H
#define _SACABITS_H 1

#define typetobin(type) const char* type##_a_binario(type num)  \
  {                             \
  return printBits(sizeof(type), &num);             \
  }


const char* getBits(size_t const size, void* ptr)
{
    unsigned char *b = (unsigned char*) ptr;
    unsigned char byte;
    int i, j;
    char *resultado = (char*)malloc(100);
    char *res = resultado;

    for (i=size-1;i>=0;i--)
    {
        for (j=7;j>=0;j--)
        {
            byte = b[i] & (1<<j);
            byte >>= j;
        *res='0'+byte;
        res++;
        }
    *res++=' ';
    }

    *res='\0';
    return res-size*9;
}

typetobin(float);
typetobin(double);
typetobin(char);
typetobin(int);

#endif /* _SACABITS_H */

Ahora, hacemos un programa de ejemplo:

1
2
3
4
5
6
7
8
9
10
#include <stdlib.h>
#include <stdio.h>
#include "sacabits.h"

int main(int argc, char *argv[])
{
  printf ("Un entero: (%d) = %s\n", 1234, int_a_binario(1234));
  printf ("Un double: (%lf) = %s\n", 1234.32, double_a_binario(1234.32));
  printf ("Un char: (%d) = %s\n", 198, char_a_binario(198));
}

O incluso podemos sacar en binario cosas más complejas, como un struct completo (eso sí, si el struct es muy grande, la salida será enorme:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdlib.h>
#include <stdio.h>
#include "sacabits.h"

struct miStruct
{
  char texto[4];
  int numero;
};

int main(int argc, char *argv[])
{
  struct miStruct test = { "HOLA", 2047 };

  printf ("Un struct: %s\n", getBits(sizeof(test), &test));
}

Con esto podemos aprender cosas muy curiosas sobre la memoria de un ordenador, o de cómo organiza C las cosas.

C++

Vamos avanzando, y es que en C++ tenemos métodos mucho más sencillos de sacar un valor en bits de una variable. Utilizando bitset, incluido en std. De la siguiente forma:

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <bitset>

int main()
{
  std::cout << "123 = " << std::bitset<8>(123)  << std::endl;
  std::cout << "1234 = " << std::bitset<16>(1234)  << std::endl;
  std::cout << "123456789 = " << std::bitset<32>(123456789)  << std::endl;
  std::cout << "12345678901234567 = " << std::bitset<64>(12345678901234567)  << std::endl;
}

Java

Venga, también lo haremos en Java en este post. En este caso, de forma sencilla, cogemos un entero y lo pasamos a binario:

1
2
3
4
5
6
7
8
public class Sacabits
{
  public static void main(String args[])
    {
    int i = 615243;
    System.out.println("Valor: " + Integer.toBinaryString(i));
    }
}

Integer.toBinaryString(numero) nos devolverá una cadena de caracteres con cada uno de los bits del número en cuestión.

PHP

Como sabéis que me gusta PHP, también quiero dejar un pequeño código en este lenguaje, aunque es lo más simple del mundo, ya que tenemos una función que nos saca directamente el valor en base2 de un número decimal:

1
2
3
<?php
echo "123: ".decbin(123)."\n";
echo "1928: ".decbin(1928)."\n";

Python

Python, como siempre, tiene cosas muy masticadas, y desde aquí podemos ver un ejemplo desde la línea de comandos de python:

1
2
3
4
>>> bin(123)
'0b1111011'
>>> "{0:b}".format(123)
'1111011'

Con el primer método, mucho más rápido veremos el valor en binario, pero con la base delante (0b), de la misma forma que podemos expresar un número en diferentes bases. Con la segunta forma, veremos directamente el valor en base 2, depende de nuestras necesidades escoger uno u otro.

Ruby

Ruby no es mi punto fuerte, pero también quería poner un ejemplo en este lenguaje. Podemos hacerlo de varias formas, entre otras, estas dos me parecen muy interesantes:

1
print "%b" % 123

y

1
print 9.to_s(2)

Ahora os toca a vosotros, ¿algún otro lenguaje con el que podamos completar este post?

Foto: ahmadreza sajadi (unsplash)

También podría interesarte....

There are 12 comments left Ir a comentario

  1. Pingback: Programadores en C++, HTML, XHTML,PHP, MySQL, CSS básico | Just another My blog Sites site /

  2. Pingback: Bailando con bits III. Mostrando el valor binario de un número [bash, C, C++, PHP, Java, Python, Ruby] | PlanetaLibre /

  3. Pingback: Cómo extraer la parte alta y la parte baja de un número con varios ejemplos en C – Poesía Binaria /

  4. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    A round of applause for bringing together the giants of web slots. Impressive work. สล็อตเว็บใหญ่ที่สุด

  5. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    It’s disheartening when your favorite slots break easily. เว็บตรง แตกง่าย

  6. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Gee… I translate writes on a similar to issue, be that as it may I never went by your blog. I added it to populars additionally i’ll be your reliable preliminary. รวมสล็อตทุกค่าย

  7. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    Can pleasantly compose on comparative themes! Welcome to here you’ll discover how it should look. ป๊อกเด้ง ออนไลน์

  8. jsimitseo /
    Usando Google Chrome Google Chrome 120.0.0.0 en Windows Windows NT

    It ought to be noticed that while requesting papers available to be purchased at paper composing administration, you can get unkind state of mind. In the event that you feel that the authority is endeavoring to cheat you, don’t purchase research project from it. เกมสล็อตโรม่า

  9. jsimitseo /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    Your online diaries propel more each else volume is so captivating further serviceable It chooses me happen for pull back repeat. I will in a blaze grab your reinforce to stay instructed of any updates. concierge doctor naples

  10. orabelle hana /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    That’s very wonderful test grade calculator

  11. WilliamSEO /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    It is fine, in any case assess the data and actualities around this right. สล็อตเว็บตรง แตกง่าย

  12. 토토사이트 /
    Usando Google Chrome Google Chrome 122.0.0.0 en Windows Windows NT

    It’s a game. Five dollars is free. Try it It’s not an easy game
    ->-> 토토사이트.COM

Leave a Reply