Hola, de nuevo no encuentro forma elegante de resolver un problema, en
principio, sencillo:
Tengo un valor numérico, ejemplo:
num = 192
Ahora quiero saber si en la representación binaria de “num” están
activos los bit 5, 6 y 7 (por separado).
Concretamente 192 = 11000000, asà que:
- bit 5: NO
- bit 6: SI
- bit 7: SI
Ahora lo intento hacer con Ruby:
Primero paso el número a binario (no encuentro forma mejor que ésta
guarrada):
num.to_s(2).to_i
=> 11000000
Ahora tendrÃa que hacer un AND binario, pero es que para que el número
sea considerado como binario debe estar en la forma:
0b11000000
¿Cómo consigo ese número en ese formato?
Luego harÃa el AND binario, para ello necesito el “num” y la máscara
para cada bit en binario.
La máscara la puedo obtener asÃ:
10**5
=> 100000
Pero estamos en las mismas, necesito:
0b100000
Y luego aplicarÃa:
-
bit 5:
0b11000000 & 0b100000
=> 0
-
bit 6:
0b11000000 & 0b1000000
=> 64
-
bit 7:
0b11000000 & 0b10000000
=> 128
Hay mucha “ñapa” ahà arriba, ¿alguna sugerencia para decorarlo un poco?
Muchas gracias.
El 20/02/08, Iñaki Baz C. [email protected] escribió:
También lo podrÃa hacer de otra forma puesto que Ruby permite máscara
binaria netre dos números enteros:
192 & 128
=> 128
Lo intento por esta vÃa:
binary = 1
N.downto(1) {binary = binary * 10}
binary
=> 1000000
Pero ahora ¿cómo paso de 1000000 a 64?
Lo podrÃa hacer asÃ:
0b1000000.to_i
=> 64
pero claro, 1000000 lo tengo en la variable “binary”, ¿cómo lo “meto”
ahà dentro? lo siguiente da error:
0b#binary.to_i
SyntaxError: compile error
(irb):139: numeric literal without digits
0b#binary.to_i
^
from (irb):139
from :0
¿Alguna idea? Gracias.
On Feb 20, 2008, at 15:18 , Iñaki Baz C. wrote:
Ahora lo intento hacer con Ruby:
Primero paso el número a binario (no encuentro forma mejor que ésta
guarrada):
num.to_s(2).to_i
=> 11000000
Ojo, ahi se hace esto:
- representacion en base 2 de 192
- eso da una cadena
- se convierte esa cadena a entero con to_i
El metodo to_i asume que la cadena esta en base 10, de manera que en
realidad has pasado de 192 a 11 millones, has obtenido un numero
distinto.
Si el numero es entero positivo se puede saber directamente si el 7o
bit por la derecha de su representacion en base 2 es 1 de este modo:
1 == num & (1 << 6)
– fxn
2008/2/20 Iñaki Baz C. [email protected]:
No obstante, no llego a entender qué hace ese “1 << 6”, ¿podrías
explicarlo un poco por favor?
Los operadores << y >> son shifts (corrimiento?) de bits a la
izquierda y derecha respectivamente. Un ejemplo:
a = 0001
a << 2
a = 0100
Básicamente lo que estás haciendo es mover todos los bits del número
“n” posiciones a la izquierda o a la derecha. Cuando haces “1 << 6”
estas obteniendo un número
así:
00100000
Que efectivamente es lo que quieres comprobar.
Si mi explicación no es muy clara puedes ir a Google y buscar ejemplos
de “Bit shift operators”
El 20/02/08, Federico B. [email protected] escribió:
Que efectivamente es lo que quieres comprobar.
Si mi explicación no es muy clara puedes ir a Google y buscar ejemplos
de “Bit shift operators”
Entendido perfectamente
Muchas gracias.
El 20/02/08, Xavier N. [email protected] escribió:
El metodo to_i asume que la cadena esta en base 10, de manera que en
realidad has pasado de 192 a 11 millones, has obtenido un numero
distinto.
Vale, no se me habÃa ocurrido hacer “to_i(2)” para los String.
Entonces puedo hacer:
N = 6 (bit 6)
N.downto(1) {binary = binary * 10}
binary
=> 1000000
binary.to_s.to_i(2)
=> 64
Me sigue pareciendo un poco guarrillo tener que hacer ese “to_s.to_i”
para cambiar la base, ¿no existe algo en plan:
binary.to_base(10)
?
Si el numero es entero positivo se puede saber directamente si el 7o
bit por la derecha de su representacion en base 2 es 1 de este modo:
1 == num & (1 << 6)
Qué buena !!!
65 & (1 << 6)
=> 64
64 & (1 << 6)
=> 64
63 & (1 << 6)
=> 0
128 & (1 << 6)
=> 0
192 & (1 << 6)
=> 64
No obstante, no llego a entender qué hace ese “1 << 6”, ¿podrÃas
explicarlo un poco por favor?
MuchÃsimas gracias.
El dÃa 20/02/08, Federico B. [email protected] escribió:
Los operadores << y >> son shifts (corrimiento?)
“Corrimiento” queda feo. Mejor “desplazamiento”
Esta forma la veo correctÃsima:
192 & 128
=> 128
Porque no usarla?
On Feb 20, 2008, at 16:03 , Xavier N. wrote:
Si el numero es entero positivo se puede saber directamente si el 7o
bit por la derecha de su representacion en base 2 es 1 de este modo:
1 == num & (1 << 6)
He recordado que ademas en Ruby se puede hacer esto
num[6] == 1
Los enteros responden a [], que da acceso directo a sus bits:
2[0] # -> 0
2[1] # -> 1
– fxn