Escriba el código más corto para invertir el orden de bits de un entero de 32 bits.
Reglas:
- Se supone que la entrada es un entero válido o equivalente de cadena si su idioma no admite valores numéricos (por ejemplo, Windows Batch).
- La salida debe ser un entero válido o una cadena equivalente si su idioma no admite valores numéricos (por ejemplo, Windows Batch).
- Biblioteca estándar solamente.
- Puede ser una función o un programa completo.
- La entrada puede ser desde
stdino como un argumento de función. - La salida debe ser
stdouto como un valor devuelto. - Si su idioma tiene una función de biblioteca integrada o estándar que hace esto en un solo paso (por ejemplo,
rbiten el ensamblaje ARM), eso no se puede usar.
Ejemplos:
Llave:
- decimal
- binario
- (marcha atrás)
- binario invertido
- salida decimal
Ejemplos:
-90(Ejemplo de 8 bits para demostración)10100110b- (marcha atrás)
01100101b101
48600000000000000000000000111100110b- (marcha atrás)
01100111100000000000000000000000b1736441856
-98480290611000101010011010001100110100110b- (marcha atrás)
01100101100110001011001010100011b1704506019
Nota: Las omisiones son juegos gratis. Si no lo dije, y no es una de las lagunas estándar , entonces está completamente permitido.

Respuestas:
Ensamblado x86, 9 bytes
En forma de bytes:
33 C0 40 D1 E9 13 C0 73 FA9 bytes.fuente
__fastcally no tenía elret.Ensamblado MMIX (28 bytes)
Números de 64 bits
Esto se ensambla para:
¿Como funciona?
La
MORinstrucción realiza una multiplicación matricial en dos cantidades de 64 bits utilizadas como dos matrices de booleanos 8x8. Un número booleano con dígitos abcdefghklmnopqr 2 se usa como una matriz como esta:La
MORinstrucción multiplica las matrices representadas por sus argumentos donde la multiplicación esandy la suma esor. Es:y además:
que es el orden inverso de los bits del número original.
Números de 32 bits
Si solo desea el reverso de un número de 32 bits en lugar de un número de 64 bits, puede usar este método modificado:
montado:
La primera multiplicación de matrices básicamente funciona así:
el octabyte correspondiente es el
#0000000001020408que cargamos en las dos primeras instrucciones. La segunda multiplicación se ve así:El octabyte correspondiente es el
#0102040810204080que creamos de la primera matriz así:La segunda multiplicación es como siempre, el código resultante tiene la misma longitud (28 bytes).
fuente
POLYinstrucción del VAX es básicamente una combinación de multiplicar y agregar con un bucle incorporado. También existen cosas similares en arquitecturas modernas (como x86), pero generalmente no tienen un bucle incorporado para evaluar un polinomio completo a la vez.Conjunto 80386 (
1312 bytes)Como una función en la sintaxis de AT&T usando la convención de llamadas cdecl.
Esta función se ensambla a la siguiente secuencia de bytes:
Desglosado en instrucciones:
Funciona así: en cada una de las 32 iteraciones del bucle, el argumento, que se encuentra en
4(%esp), se desplaza a la derecha en una posición. El último bit se desplaza implícitamente al indicador de acarreo. Laadcinstrucción agrega dos valores y agrega el valor del indicador de acarreo al resultado. Si agrega un valor a sí mismo, es decir%eax, efectivamente lo desplaza a la izquierda en una posición. Esto esadc %eax,%eaxuna manera conveniente de desplazarse hacia la izquierda%eaxen una posición mientras se desplaza el contenido de la bandera de acarreo al bit de orden inferior.Repito este proceso 32 veces para que
4(%esp)se vierta todo el contenido de%eax. Nunca inicializo explícitamente%eaxya que sus contenidos anteriores se desplazan durante el ciclo.fuente
C,
635248Versión original:
Versión actualizada (con cambios sugeridos por Allbeert , es1024 y Dennis ):
Nota: Dado que la segunda versión omite la configuración
r=0, el código supone que anintes de 32 bits. Si esta suposición es falsa, lo más probable es que la función produzca un resultado incorrecto, dependiendo del estado inicial de larentrada a la función.Versión final (con más cambios sugeridos por Dennis y Alchymist ):
Nota: Esto coloca la declaración de las variables de trabajo
ryien la lista de parámetros. Los parámetros son los siguientes:nes el número que se va a invertir en bits.ryison variables de trabajo que deben pasarse como 0.fuente
inttipo de función, y también cambiarreturn ra algo asíi=rcomo la mayoría de los compiladores de C tienden a dejar el resultado de la última operación en el registro de retorno. Funcionó en gcc y cl para mí.r(n){...}r(int n){...}intaint r=0,i=32;menos que los saque del cuerpo de la función.-1 >> 1es-1para AS y2**31 - 1para LS, mientras que-1 / 2es0.ryicomo argumentos? Ahorraría tres bytes más ...Julia 0.2, 33 bytes
Hace lo que parece.
bitsle da la representación de bits (respetando el complemento de dos).parseintno le importa el complemento de dos, pero devuelve un entero de 32 bits, por lo que el complemento de dos simplemente se maneja por desbordamiento.De acuerdo con los registros de cambios, se agregó la detección de desbordamiento
parseinten Julia 0.3, por lo que esto podría no funcionar más.fuente
Pitón 2, 50
En general, lo mismo que mi solución Pyth. Tome el mod de entrada 2 ** 32, convierta a binario acolchado de 32 bits, invierta, convierta la picadura binaria de nuevo a decimal e imprima.
fuente
CJam, 15 bytes
Pruébalo en línea.
Se utilizó el comodín "Juego libre": la salida siempre será un entero sin signo.
Casos de prueba
Cómo funciona
fuente
JavaScript (E6) 37
39 40 50Función, entrada de número y devolución de número invertido.
Algoritmo más básico, probablemente se puede jugar más golf con algún truco inteligente.Editar recursión en lugar de bucle
Editar 2 Siguiendo la sugerencia de @bebe en
k*2lugar dek<<1Editar 3 Algo que me había perdido en absoluto: es un bucle completo de 32 bits, no es necesario inicializar k. Gracias @FUZxxl
Era
Prueba en la consola FireFox, prueba usando números en OP y algunos números más aleatorios de 16 y 32 bits
Ejemplo de salida de prueba
fuente
b=k=0,R=v=>b++<32?R(v>>1,k+=k+(v&1)):kpara un solo uso yR=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):kes reutilizablek<<1vuelvek*2y sev>>1vuelvev/2. funcionó durante 486. No sé sobre otros casos de pruebax86 ensamblado, 10 bytes
Esto supone entrada en eax, salida en edx. (Además, en la salida eax es cero y CF y ZF están configurados, si a alguien le importa).
En lugar de un contador, se introduce un 1 adicional al principio como marcador de fin de datos
fuente
retinstrucción de retorno de la función e implementar cdecl (es decir, cambiorcr %eaxarcr 4(%esp)yrcl %edxarcl %eax), que terminan con un byte adicional para elrety otros dos bytes para la referencia de memoria. Aún así, una buena solución.J (
171513 bytes)Aquí hay una definición explícita para explicar lo que hace:
#: yrepresentaycomo un número base 2 usando tantos lugares como sea necesario.x {. ytoma|x(magnitud dex) elementos dey, desde el frente sixes positivo, desde la parte posterior sixes negativo. Si tomamos más elementos que los presentes, el resultado se rellena con ceros._32 {. #: yefectivamente almohadillas#: ya 32 bits.|. yvolteay, i. invierte el orden de los artículos eny.#. yinterpretaycomo un número de base 2.fuente
Dyalog APL , 10 bytes
2⊥desde-base-2 de⌽el reverso⎕entrada numérica⊤⍨en el sistema numérico que consiste en32/232 bitsTryAPL en línea!
fuente
Python - 89
Python representa números binarios negativos como simplemente
-0b{positive_number}. Entonces, para lidiar con esto, complemente los números negativos y luego XOR con todos los 1.Después de eso, cree la representación de cadena del número entero basada en el formato
{:032b}que proporciona la representación de 32 bits del número. Finalmente, invierta la cadena y vuelva a convertirla en un número entero.EDITAR
Gracias a @ Martin Büttner por señalar el problema del complemento a dos. Si
ntermina en un complemento de 1 por dos, la versión invertida sería negativa.Afortunadamente, como se explicó anteriormente, a Python le gustan los números binarios negativos de una manera bastante simple. Afortunadamente, la
intfunción de Python permite caracteres de signos opcionales en su primer argumento.Entonces, agregue un signo menos si
nes extraño para satisfacer el complemento de dos.fuente
['','-'][n%2]es'-'*(n%2).Pyth ,
333222Explicación:
Golfs:
33 -> 32: movido agregar a antes de invertir para guardar una cotización final.
32 -> 22: Se utilizó Q mod 2 ^ 32 en lugar de maquinaria complicada. Combinó ambas cuerdas en una.
Casos de prueba:
fuente
GNU dc, 27 bytes
Salida:
Bash + coreutils, 45 bytes
Salida:
Función C, 89 bytes
La misma idea que /codegolf//a/36289/11259 - usando los trucos de Stanford bit twiddling . No va a ganar el golf, pero de todos modos es interesante:
Salida:
fuente
Función Java, 64 caracteres.
También debería funcionar en C.
fuente
PHP, 46 bytes
Versiones en linea
o
fuente
substres innecesario (-12 bytes). Deberías mencionar cómo ejecutarlos.-984802906?<?=bindec(strrev(sprintf("%064b",$argn<<32)));JS 115
Bueno, eso no se ve bien en absoluto: D
El método de @Florian F en JS tiene 53 bytes de longitud:
fuente
it may be a functionregla significa que no necesita la alerta o avisoC #
8174Operaciones de bit que probablemente se pueden hacer más cortas en todos los lenguajes de programación.
Básicamente, recorre todas las potencias de 2 hasta un máximo entero + 1 (que se convierte en una potencia de dos) y desde (2,147,483,647 + 1) = 0 puedo recorrer a 0. Desplazar bit de izquierda a derecha para mover el bit al primero posición. El último bit en el lugar 32 va 31 pasos a la derecha, el segundo último va a 30 etc. Así que al usar el operador AND con 1 sabré si es 1 o 0. Si es 1, agregaré el valor i actual al resultado y devolverlo.
fuente
icuando lo declara, y guardar un byte eliminandoi++del bucle for, y en lugar de comparar el resultado de1&...con 0, puede eliminar la instrucción if por completo y multiplicaripor el resultado que dar|=i*(1&(V>>(31-l++)));dentro del bucleC # 142
Expandido
fuente
Python - 37
Similar a la solución de @ isaacg.
fuente
C ++, 160
Este no es el más corto, sin embargo, solo usa 24 operaciones.
Tomado del libro Hacker's Delight.
Golfizado:
Sin golf:
fuente
Haskell, 145 - no hay operaciones bit a bit
El giro de bits me parece la antítesis de Haskell, por lo que he evitado el uso de operadores bit a bit. El programa resultante ciertamente no es el concursante más corto, pero pensé que el uso de las matemáticas en lugar de las tonterías era interesante al menos.
Explicación
0sy1, el bit menos significativo primero dividiendo repetidamente entre 2 y tomando el resto0s al final de esta lista0y1en un entero suponiendo que el bit más significativo es el primero (repetido doble y agregar).No estoy muy seguro de qué constituye "la biblioteca estándar" en Haskell, así que asumí que Data.Tuple y Data.List estaban bien (son bastante estándar).
Además, la salida es un entero de 32 bits sin signo, ya que cambiar eso me costaría bytes: estoy argumentando esto en "las omisiones son juegos gratis".
fuente
PHP,
4641 bytespruébalos en línea
bit a bit ... más o menos. Corre como tubería con
php -nR '<code>'.PHP, 46 bytes
una solución bit a bit pura; correr como tubería con
-nR.PHP,
4759 bytesotro enfoque incorporado; guardar en archivo y ejecutar como tubería con
-F.fuente
Perl - 60
+1 para la bandera p (avíseme si estoy contando esto mal).
Corre con:
fuente
C ++ 69
fuente
e;i;? Las declaraciones sin tipo no son un C ++ válido. Para las variables ni siquiera es válida C.int r(int n){int e=0,i=0;for(;i<32;)e=e*2|1&n>>i++;return e;}61 bytes :)R, 45
Ejemplos:
Siempre justo por debajo de las respuestas de Python. Esa maldita palabra clave de función.
fuente
Rubí,
4341 bytesdef r(n)(0..31).inject(0){|a,b|a*2+n[b]}endEn Ruby, el uso de la notación de índice de paréntesis (foo [i]) devuelve el bit en el enésimo lugar.
--Editar--
Refactorizar la
injectfuncionalidad reduce un par de bytesdef r(n)z=0;32.times{|i|z=z*2+n[i]};z;endfuente
Perl5: 46
Nada sofisticado. Desplaza la salida a la izquierda, copia lsb antes de cambiar la fuente a la derecha.
fuente
Clojure,
202156142fuente
Perl (37 + 1)
básicamente un puerto de la solución C por Todd Lehman
perl -E '$t=<>;map$r=2*$r|1&$t>>$_,0..31;say$r'fuente