style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Numeros binarios

Hola a todos, nuevamente necesito su ayuda, en la universidad el profe nos dejo un ejercicio, el cual se basa en lo siguiente :

"Para un numero entero positivo N, hallar el complemento y el reverso del numero representado en el sistema binario, y mostrarlos en el sistema decimal. Por ejemplo, si n = 2006 (11111010110 en binario) entonces su complemento es p = 42 (00000101010)
en binario) y su reverso es q = 863 (01101011111 en binario)"

El programa debera de mostrar los valores de p y q, osea 41 y 863.

Les comento que el profe nos prohibio que en el programa convirtamos el numero N a binario, ya encontre la forma de hallar el complemento sin tener que pasar N a binario :

* Para hallar la representacion decimal del complemento de la representacion binaria de N no es necesario pasar el numero a binario ya que se podria hallar asi :

int exponente = ( int ) ( Math.ceil( Math.log( N ) / Math.log(2) );

int complemento = ( int )( Math.pow( 2, exponente ) - N  );

* Pero aun me falta encontrar la forma de hallar el reverso de N sin tener que convertir N a binario, por eso recurro a ustedes , no quiero que me den codigo, sino una idea, o sugerencia, algo por donde empezar, ya que he estado buscando en google y libros pero no encuentro la forma de hacerlo.
Ojala me puedan ayudar. Hasta luego

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

BitSet

eso de "convertir el número a binario" significa que no pueden usar BitSet o algo así? O a manejar bits de manera individual?

El complemento lo puedes obtener haciendo un NOT de bits en Java, con el operador ~, pero no te va a dar los números que dices porque estás manejando 11 bits y en Java si guardas los números en un int pues son 32 bits o en un short son 16 bits y además son con signo.

Lo único que podrías hacer sería tomar el número binario de entrada como una cadena y convertirlo a un int y manejar solamente tantos bits como sea necesario, pero todas las conversiones las vas a tener que hacer a mano, bit por bit:

String binario = "101";
int num = 0;
//Aqui empezamos teniendo el bit mas grande
//<< es bitshift a la izquierda
int bit = 1 << (binario.length() - 1);
for (int i = 0; i < binario.length(); i++) {
  //si encuentras un digito que sea 1...
  if (binario.charAt(i) == '1') {
    //OR de bits entre el número que llevamos y el bit actual
    num |= bit;
  }
  //bitshift a la derecha
  bit = bit >> 1;
}

Y de manera similar tendrías que hacer las operaciones de negación y reverso, es decir, bit por bit solamente considerando los caracteres que tiene el número original como cadena.

Imagen de XinefPro

Muchas gracias

Diste en el blanco, me sirvio mucho tu ayuda, gracias x todo xD

Java...

Qué tal,

Manipulación de bits, datos a bajo nivel y empaquetamiento/desempaquetamiento de octetos o pedazos de bytes nunca ha sido uno de los trabajos fuertes de Java. Obviamente un lenguaje es simplemente una herramienta, pero así como en la vida cotidiana, cada herramienta generalmente tiene uno o mas fines específicos. Es decir, clavar un clavo con un desarmador definitivamente es posible, pero cuesta un poco de trabajo extra. De la misma manera Java generalmente es evitado para fines de manipulación de datos a bajo nivel, en cuestion de bits y bytes.

Antes de mostrar una solución posible a tu problema sobre "inversión de bits", cabe señalar que lo que dice ezamudio sobre el tamaño para la representación de cada tipo es MUY importante. Un número como 2006 representado como int, al invertirlo no necesariamente tiene que darte 863 como int, por qué? porque los ceros de la izquierda de una cantidad de 32 bits serán movidos a la derecha. El siguiente punto es signo, Java no permite representar números sin signo como tipos nativos, y una de las soluciones es promover tu tipo de dato al siguiente arriba de la jerarquía. Por ejemplo, un short, 16 bits, 2 bytes, si quieres representar el número 2^15 (ya que en Java un Short.MAX_VALUE es 2^15 -1), necesitas promover tu tipo a un int y tener cuidado que la operación que realices también sea promovida a este tipo de dato, incluyendo sus argumentos. Y bueno, podría seguir agregando otros ejemplos en los que Java no se presta de manera nata para resolver algunas de estas situaciones, sobre todo presentadas en programación de sistemas y afines.

Volviendo al punto de tu problema, una solución que permite encontrar el inverso de un número, sin necesidad de convertirlo a una cadena de bits, y analizar uno a uno de ellos es la siguiente solución presentada por Henry Warren en "Hackers Delight", un libro excepcional para aquellos que necesitan realizar optimizaciones pesadas ("bit twiddling") como aquellos que escriben compiladores.

La solución la escribí en Perl por cuestiones antes citadas y comodidad, pero traducirla a Java o cualquier otro lenguaje no debería costarte ningún trabajo:

sub rev {
        my $n = shift;

        $n = ($n & 0x55555555) <<  1 | ($n & 0xaaaaaaaa) >>  1;
        $n = ($n & 0x33333333) <<  2 | ($n & 0xcccccccc) >>  2;
        $n = ($n & 0x0f0f0f0f) <<  4 | ($n & 0xf0f0f0f0) >>  4;
        $n = ($n & 0x00ff00ff) <<  8 | ($n & 0xff00ff00) >>  8;
        $n = ($n & 0x0000ffff) << 16 | ($n & 0xffff0000) >> 16;

        my $r = $n & (-$n); # Esto te dará el 1 más a la derecha

       # $r tendrá algo como 100000000 el cual ahora mediante
       # el ciclo de abajo voy contando la cantidad de ceros a la
       # derecha hasta llegar al 1, y el contador final es la cantidad
       # de bits a recorrer del número invertido.
       #
       # (~n & (n + 1) te da una cantidad con el zero mas a la derecha
       # convertido en '1', y lo comparo contra 0x1 (uno) para ir contando
       # todos los ceros, hasta que al encontrarme con el 1 la condición
       # ya no se cumpla.
        my $c = 0;
        while ((~$r & ($r + 1)) & 0x1) {
                $c++;
                $r >>= 1;
        }

        return $n >> $c;
}

my $n = 2006;
printf ("%b\n", $n);
printf ("%b\n", rev($n));
print "$n  -> ", rev($n), "\n";

La parte propuesta por Henry W. es la primer parte de la función rev, la cual simplemente va intercambiando los bits de la izquierda por los de la derecha, pero ojo, lo hace para todos los bits que conforman tu tipo de dato (32 para int, 16 para short, tomando mi plataforma como base). La siguiente parte la agregué para poder
eliminar todos los 0's de la derecha que vienen de los ceros sobrantes del tamaño del tipo de dato (que estaban a la izquierda) en el que almacenes tu número y al final simplemente recorro dicho número hacia la derecha N veces, tantos ceros encontré.

Mi pregunta es, tu profesor realmente les pidió pensar en una solución similar a esta? Me suena a que los quiere acomplejar. Ya que generalmente inversión de bits no es muy común utilizarla, pero por otro lado, inversión de bytes si lo es, y el ejemplo más común es la conversión del orden de bytes de "little-endian" a "big-endian" que muchos lenguajes vienen equipados con funciones para facilitarte esto (como ByteBuffer de Java).

Un saludo,

Imagen de juanfranc520

Complemento

Bueno XinefPro, tengo una duda? que operacion hiciste para sacar el complemento del 2006 (11111010110), es complemento a 1, complemento a 2, yo creo que debes tener en cuenta eso, ademas se debe tener en cuenta que para numeros positivos es muy diferente que para negativos asi como los complementos, si quieres mira esta pagina http://www.carlospes.com/curso_representacion_datos/05_03_complemento_a_... y si no entiendes algo podemos hablar, ademas quisiera saber bien como hiciste ese complemento del 2006 (11111010110) a 42 (00000101010), si tienes algun error y es como pienso es un poco mas sencillo, el ejemplo de amnesiac esta excelente, pero es muy complicado, es un codigo muy maquina donde se esta trabajando con hexadecimal, pero esta muy bueno, cualquier duda me dices, yo te puedo ayudar un poco sobre el manejo de datos binario pues vi una materia que se llama electronica digital y todo el berraco semestre es 1 y 0.

Saludos.

Imagen de XinefPro

Disculpen

por no haber respondido, lo que pasa es que no he podido tener acceso a internet estas ultimas semanas,
miren derepente no me explique bn en el primer post, por eso aqui les dejo el problema tal y como nos lo dejo el profe , se los dejo en una imagen :

subir imagenes

Imagen de ezamudio

Sigue igual

Pues entendi lo mismo leyendo la tarea original. El complemento finalmente es el NOT por bits y el reverso es poner los mismos bits de derecha a izquierda (o sea por ejemplo 100100 su reverso es 001001 y su complemento es 011011)

Lo mencionado en cuanto al numero de bits sigue aplicando. La restriccion de que N sea menor a 4mil millones seguramente es para que puedas manejar numeros de 32 bits sin signo (cosa que en Java solo puedes lograr con un long porque no hay unsigned int).

Imagen de Shadonwk

esta sencilla la tareita...

esta sencilla la tareita... deberias postear el codigo fuente para ver como lo resolviste..

Imagen de XinefPro

Bueno si, puse una imagen

Bueno si, puse una imagen del problema original , porque me habia mareado con los comentarios, de que si era " complemento a 1 , complemento a 2 " , " de que si es numero negativo o no" , "de que se tienen que correr unos bits " , ufff todo eso me mareo, no fue facil diferirlo xD, gracias a eso aprendi mas cositas de las que pensaba aprender..

Imagen de MrCalamitus

Duda de Bits

HOla ,leyendo su discucion encontre que tengo un problema similar :

Tengo un entero -8469523 que saco del RGB de un pixel en una imagen
el cual al convertirlo a Binary String para manipular sus canales me da: 11111111011111101100001111101101
mi probema viene en convertir cuando intento revertir el binaryString a int me saca un NUMBER FORMAT exception
por que el su length() es de 32 lo qu quiero es poder convertir un Stringbinary en un entero con signo como el que me arroja al rpicipio

Garcias

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">