Ordem de bits reversa de números inteiros de 32 bits

21

Escreva o código mais curto para reverter a ordem dos bits de um número inteiro de 32 bits.

Regras:

  1. A entrada é assumida como um número inteiro válido ou equivalente a sequência se o seu idioma não suportar valores numéricos (por exemplo, lote do Windows).
  2. A saída deve ser um número inteiro válido ou equivalente a sequência se o seu idioma não suportar valores numéricos (por exemplo, lote do Windows).
  3. Somente biblioteca padrão.
  4. Pode ser uma função ou um programa completo.
  5. A entrada pode ser de stdinou como um argumento de função.
  6. A saída deve ser stdoutou como um valor retornado.
  7. Se o seu idioma tiver uma função de biblioteca interna ou padrão que faça isso em uma etapa (por exemplo, rbitna montagem do ARM), isso não poderá ser usado.

Exemplos:

Chave:

  1. decimal
    • binário
    • (marcha ré)
    • binário invertido
    • saída decimal

Exemplos:

  1. -90 (Exemplo de 8 bits para demonstração)

    • 10100110b
    • (marcha ré)
    • 01100101b
    • 101
  2. 486

    • 00000000000000000000000111100110b
    • (marcha ré)
    • 01100111100000000000000000000000b
    • 1736441856
  3. -984802906

    • 11000101010011010001100110100110b
    • (marcha ré)
    • 01100101100110001011001010100011b
    • 1704506019

Nota: Omissões são jogos grátis. Se eu não disse isso, e não é uma das brechas padrão , é completamente permitido.

Isiah Meadows
fonte
O que se entende por "omissões" em "omissões são jogos grátis"?
Todd Lehman
11
Qualquer coisa que não esteja explicitamente declarada nas regras.
Isiah Meadows
Uma tabela estática de 16GB seria contada como parte do tamanho do programa?
Hot Licks
@ HotLicks De acordo com a interpretação típica do programa, sim.
FUZxxl
linguagem que suporta apenas entradas de 8 bits, podemos receber entrada como quatro números de 8 bits?
Sparr

Respostas:

0

montagem x86, 9 bytes

    xor eax, eax
    inc eax
myloop:
    shr ecx, 1
    adc eax, eax
    jnc short myloop

Em formato de byte:, 33 C0 40 D1 E9 13 C0 73 FA9 bytes.

Myria
fonte
Isso é exatamente o mesmo desde que minha solução se você (a) obedecer à convenção de chamada do cdecl e (b) realmente retornar da função.
FUZxxl
@FUZxxl De alguma forma, eu não vi sua versão. Você está completamente correto. Eu estava pensando __fastcalle não tinha o ret.
Myria
24

Montagem MMIX (28 bytes)

Números de 64 bits

rbit:
    SETH $1,#0102 # load matrix in 16-byte steps
    ORMH $1,#0408
    ORML $1,#1020
    ORL  $1,#4080
    MOR  $0,$1,$0 # multiplication 1
    MOR  $0,$0,$1 # multiplication 2
    POP  1,0      # return

Isso monta para:

rbit:
    E0010102 # SETH $1,#0102
    E9010408 # ORMH $1,#0408
    EA011020 # ORML $1,#1020
    EB014080 # ORL  $1,#4080
    DC000100 # MOR  $0,$1,$0
    DC000001 # MOR  $0,$0,$1
    F8010000 # POP  1,0

Como funciona?

A MORinstrução executa uma multiplicação de matrizes em duas quantidades de 64 bits usadas como duas matrizes 8x8 de booleanos. Um número booleano com dígitos abcdefghklmnopqr 2 é usado como uma matriz como esta:

/ abcd \
| efgh |
| klmn |
\ opqr /

A MORinstrução multiplica as matrizes representadas por seus argumentos onde está a multiplicação ande a adição or. Isto é:

/ 0001 \      / abcd \      / opqr \
| 0010 |  \/  | efgh |  --  | klmn |
| 0100 |  /\  | klmn |  --  | efgh |
\ 1000 /      \ opqr /      \ abcd /

e além disso:

/ opqr \      / 0001 \      / rqpo \
| klmn |  \/  | 0010 |  --  | nmlk |
| efgh |  /\  | 0100 |  --  | hgfe |
\ abcd /      \ 1000 /      \ dcba /

que é a ordem inversa dos bits do número original.

Números de 32 bits

Se você deseja apenas o inverso de um número de 32 bits em vez de um número de 64 bits, pode usar este método modificado:

rbit:
    SETL   $1,#0408 # load first matrix in two steps
    ORML   $1,#0102
    MOR    $1,$1,$0 # apply first matrix
    SLU    $2,$1,32 # compile second matrix
    16ADDU $1,$2,$1
    MOR    $1,$0,$1 # apply second matrix
    POP    1,0      # return

montado:

rbit:
    E3010408 # SETL   $1,#0408
    EA010102 # ORML   $1,#0102
    DC010001 # MOR    $1,$1,$0
    3B020120 # SLU    $2,$1,32
    2E010201 # 16ADDU $1,$2,$1
    DC010001 # MOR    $1,$0,$1
    F8010000 # POP    1,0

A primeira multiplicação de matrizes funciona basicamente assim:

/ 0000 \      / 0000 \      / 0000 \
| 0000 |  \/  | 0000 |  --  | 0000 |
| 0001 |  /\  | abcd |  --  | efgh |
\ 0010 /      \ efgh /      \ abcd /

o octabyte correspondente é o #0000000001020408que carregamos nas duas primeiras instruções. A segunda multiplicação é assim:

/ 0000 \      / 0001 \      / 0000 \
| 0000 |  \/  | 0010 |  --  | 0000 |
| efgh |  /\  | 0100 |  --  | hgfe |
\ abcd /      \ 1000 /      \ dcba /

O octabyte correspondente é o #0102040810204080que criamos a partir da primeira matriz como esta:

SLU $2,$1,#32   # $2 = #0102040800000000
16ADDU $1,$2,$1 # $2 = $2 + $1 << 4
                     = $2 + #0000000010204080
                #    = #0102040810204080

A segunda multiplicação é comercial, como de costume, o código resultante tem o mesmo comprimento (28 bytes).

FUZxxl
fonte
11
é a primeira vez que ouço sobre a instrução de multiplicação de matrizes em um CPU
phuclv
@ LưuVĩnhPhúc: Não é uma multiplicação de matrizes, mas o VAX tinha uma instrução para avaliar um polinômio .
Nneonneo
11
@nneonneo A POLYinstrução do VAX é basicamente um multiplique e adicione com um loop embutido. Coisas semelhantes também existem em arquiteturas modernas (como x86), mas elas geralmente não têm um loop interno para avaliar um polinômio inteiro de uma só vez.
FUZxxl
12

80386 montagem ( 13 12 bytes)

Como uma função na sintaxe da AT&T usando a convenção de chamada cdecl.

    # reverse bits of a 32 bit word
    .text
    .globl rbit
    .type rbit,@function
rbit:
    push $32       # prepare loop counter
    pop %ecx
0:  shrl 4(%esp)   # shift lsb of argument into carry flag
    adc  %eax,%eax # shift carry flag into lsb
    loop 0b        # decrement %ecx and jump until ecx = 0
    ret            # return

Essa função é montada na seguinte sequência de bytes:

6a 20 59 d1 6c 24 04 11 c0 e2 f8 c3

Dividido em instruções:

6a 20       push $32
59          pop %ecx
d1 6c 24 04 shrl 0x4(%esp)
11 c0       adc  %eax,%eax
e2 f8       loop .-6
c3          ret    

Funciona assim: em cada uma das 32 iterações do loop, o argumento, localizado em 4(%esp), é deslocado à direita por uma posição. O último bit é implicitamente deslocado para o sinalizador de transporte. oadc instrução adiciona dois valores e adiciona o valor do sinalizador de transporte ao resultado. Se você adiciona um valor a si mesmo, ou seja %eax, efetivamente o desloca para a esquerda em uma posição. Isso é adc %eax,%eaxuma maneira conveniente de mudar para a esquerda %eaxem uma posição enquanto muda o conteúdo da bandeira de transporte para o bit de ordem baixa.

Repito esse processo 32 vezes para que todo o conteúdo de 4(%esp)seja despejado %eax. Eu nunca inicializo explicitamente, %eaxpois seu conteúdo anterior é deslocado durante o loop.

FUZxxl
fonte
+1 Obrigado pela sua última frase, agora é óbvio, mas eu perdi isso.
edc65 17/08/14
11
Estou sempre feliz em ver montagem soluções aqui :)
user1354557
8

C,    63    52   48

Versão original:

int r(int n){int r=0,i=32;for(;i--;r=r<<1|n&1,n>>=1);return r;}

Versão atualizada (com alterações sugeridas por Allbeert , es1024 e Dennis ):

r(n){int r,i=32;for(;i--;r=r*2|n&1,n>>=1);return r;}

Nota: Como a segunda versão omite a configuração r=0, o código está assumindo que um inté de 32 bits. Se essa suposição for falsa, a função provavelmente produzirá um resultado incorreto, dependendo do estado inicial der entrada na função.


Versão final (com outras alterações sugeridas por Dennis e Alchymist ):

r(n,r,i){for(;32-i++;r=r*2|n&1,n>>=1);return r;}

Nota: Isso coloca a declaração das variáveis ​​de trabalho re ina lista de parâmetros. Os parâmetros são os seguintes: né o número a ser revertido em bits. re isão variáveis ​​de trabalho que devem ser passadas como 0.

Todd Lehman
fonte
11
Você pode remover o inttipo de função e também mudar return rpara algo como a i=rmaioria dos compiladores C tende a deixar o resultado da última operação no registro de retorno. Funcionou em gcc e cl para mim.
Allbeert
11
Você poderia raspar mais 4 bytes usando r(n){...}em vez der(int n){...}
es1024
2
@FUZxxl você não pode largar o intem int r=0,i=32;menos que você movê-los para fora do corpo da função.
precisa saber é o seguinte
11
@FUZxxl: Não devo comentar quando estou cansado ... Mudança e divisão aritmética não são equivalentes; o último volta para zero, enquanto o primeiro volta para o infinito negativo. -1 >> 1é -1para AS e 2**31 - 1LS, enquanto -1 / 2é 0.
Dennis
11
@ Todd: Qualquer razão que você não definiu re icomo argumento? Pouparia mais três bytes ...
Dennis
5

Julia 0.2, 33 bytes

f(n)=parseint(reverse(bits(n)),2)

Faz o que parece.

bits fornece a representação de bits (respeitando o complemento de dois). parseintnão se importa com o complemento de dois, mas retorna um número inteiro de 32 bits; portanto, o complemento de dois é simplesmente tratado pelo estouro.

De acordo com os changelogs, a detecção de estouro foi adicionada parseintna Julia 0.3, portanto, isso pode não funcionar mais.

Martin Ender
fonte
5
Este é um código de produção, não um código de golfe! xD Acho que a Julia é ótima.
cjfaure
4

Python 2, 50

print int("{:032b}".format(input()%2**32)[::-1],2)

Em geral, o mesmo que minha solução Pyth. Pegue a entrada mod 2 ** 32, converta em binário acolchoado de 32 bits, inverta, converta a picada binária de volta em decimal e imprima.

isaacg
fonte
4

CJam, 15 bytes

li4H#+2bW%32<2b

Experimente online.

Coringa de "jogo grátis" usado: a saída sempre será um número inteiro sem sinal.

Casos de teste

$ cjam reverse32.cjam <<< 486; echo
1736441856
$ cjam reverse32.cjam <<< -984802906; echo
1704506019

Como funciona

li   " Read from STDIN and cast to integer. ";
4H#+ " Add 4 ** 17 to avoid special cases. ";
2b   " Convert into array of digits in base 2. ";
W%   " Reverse the order. ";
32<  " Discard the 33th and all following digits. ";
2b   " Convert the array of digits into an integer. ";
Dennis
fonte
4

JavaScript (E6) 37 39 40 50

Função, número de entrada e retorno do número invertido. Algoritmo mais básico, provavelmente pode ser jogado mais com algum truque inteligente.

Editar recursão em vez de loop

Editar 2 Seguindo a sugestão @bebe em k*2vez dek<<1

Edit 3 Algo que eu tinha perdido: é um loop completo de 32 bits, sem a necessidade de inicializar k. Obrigado @FUZxxl

R=(v,b=32,k)=>b?R(v>>1,b-1,k*2|v&1):k

isso foi

R=v=>{for(k=b=0;b++<32;)k+=k+(v&1),v>>=1;return k}

Teste no console do FireFox, teste usando números no OP e alguns números aleatórios de 16 e 32 bits

Bin=x=>('0'.repeat(32)+(x<0?-x-1:x).toString(2)).slice(-32).replace(/./g,d=>x>0?d:1-d),
Dec=x=>(' '.repeat(11)+x).slice(-11),
R16=_=>Math.random()*65536|0,  
R32=_=>(Math.random()*65536<<16)|R16(),  
[-90,486,-984802906,R16(),R16(),R16(),R32(),R32(),R32(),R32()]
 .forEach(n=> console.log(Dec(n)+' '+Bin(n)+' '+Dec(R(n))+' '+Bin(R(n))))

Exemplo de saída de teste

        -90 11111111111111111111111110100110  1711276031 01100101111111111111111111111111
        486 00000000000000000000000111100110  1736441856 01100111100000000000000000000000
 -984802906 11000101010011010001100110100110  1704506019 01100101100110001011001010100011
      45877 00000000000000001011001100110101 -1395851264 10101100110011010000000000000000
      39710 00000000000000001001101100011110  2027487232 01111000110110010000000000000000
      56875 00000000000000001101111000101011  -730136576 11010100011110110000000000000000
-1617287331 10011111100110100010011101011101 -1159439879 10111010111001000101100111111001
-1046352169 11000001101000011110111011010111  -344488573 11101011011101111000010110000011
 1405005770 01010011101111101010111111001010  1408597450 01010011111101010111110111001010
  -35860252 11111101110111001101000011100100   655047615 00100111000010110011101110111111
edc65
fonte
b=k=0,R=v=>b++<32?R(v>>1,k+=k+(v&1)):kpara uso individual e R=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):ké reutilizável
bebe
@bebe :( Eu estava revisando a minha resposta usando recursão e perdeu toda a ler o seu comentário ...
edc65
2
você está em 38 bytes se k<<1torna k*2e v>>1se torna v/2. ele trabalhou para 486. Eu não sei sobre outros casos de teste
bebe
11
@bebe v / 2 não funcionará para números negativos. 486/512 == 0,9 ... e 486 >> 9 == 0, trunc é o mesmo. Mas -90/128 == -0,7 ... e -90 >> 7 == - 1
edc65
4

x86, 10 bytes

   f9                      stc    
   d1 d8            1:     rcr    %eax
   74 05                   je     2f
   d1 d2                   rcl    %edx
   f8                      clc    
   eb f7                   jmp    1b
                    2:

Isso assume entrada em eax, saída em edx. (Além disso, na saída, o eax é zero e CF e ZF são definidos, se alguém se importa).

Em vez de um contador, um 1 adicional é inserido no início como marcador de fim de dados

Hagen von Eitzen
fonte
Na verdade, ele tem o mesmo tamanho da minha solução, que é três bytes maior. Se você adicionar as retinstruções para retornar da função e implementar o cdecl (ou seja, alterar rcr %eaxpara rcr 4(%esp)e rcl %edxpara rcl %eax), você terá um byte extra para os rete outros dois bytes para a referência de memória. Ainda assim, uma boa solução.
FUZxxl
3

J ( 17 15 13 bytes)

_32#.@|.@{.#:

Aqui está uma definição explícita para explicar o que faz:

3 : '#. |. _32 {. #: y'
  1. #: yrepresenta ycomo um número base 2 usando quantos lugares forem necessários.
  2. x {. ypega |x(magnitude de x) itens de y, da frente, se xpositivo, e de trás, se xnegativo. Se pegarmos mais itens do que o presente, o resultado será preenchido com zeros. _32 {. #: yefetivamente pads #: ypara 32 bits.
  3. |. yvira y, i. inverte a ordem dos itens em y.
  4. #. y interpreta ycomo um número de base 2.
FUZxxl
fonte
3

Dyalog APL , 10 bytes

2⊥⌽⎕⊤⍨32/2

2⊥ da base 2 de

o invertido

entrada numérica

⊤⍨ no sistema numérico que consiste em

32/2 32 bits

TryAPL online!

Adão
fonte
2

Python - 89

def r(n):
 if n<0:n=~n^0xFFFFFFFF
 print int(['','-'][n%2]+'{:032b}'.format(n)[::-1],2)

Python representa números binários negativos de maneira simples -0b{positive_number}. Então, para lidar com isso, complemente números negativos e depois XOR com todos os 1s.

Depois disso, crie a representação de seqüência de caracteres do número inteiro com base no formato {:032b}que fornece a representação de 32 bits do número. Finalmente, inverta a string e volte a transformá-la em um número inteiro.

EDITAR

Agradecemos a @Martin Büttner por apontar a questão do complemento de dois. Se nterminar em um 1, por complemento de dois, a versão invertida seria negativa.

Felizmente, como explicado acima, o Python gosta de números binários negativos de uma maneira bem simples. Felizmente, a intfunção do Python permite caracteres de sinal opcionais em seu primeiro argumento.

Então agora, adicione um sinal de menos se nfor ímpar para satisfazer o complemento de dois.

BeetDemGuise
fonte
@ MartinBüttner Obrigado. Perdi essa possibilidade a princípio. O novo código lida melhor com o complemento de dois.
BeetDemGuise
2
Você pode jogar um pouco mais: ['','-'][n%2]é '-'*(n%2).
Justin justin
2

Pitão , 33 32 22

v_%"%032db0"vsc%Q^2 32

Explicação:

                 Q             Evaluated input.
                %Q^2 32        Q mod 2^32. Same 32 bit binary representation as Q.
             vsc%Q^2 32        Convert to binary string, then that to decimal int.
   %"%032db0"vsc%Q^2 32        Pad above number to 32 bits, and append b0.
  _%"%032db0"vsc%Q^2 32        Reverse it.
 v_%"%032db0"vsc%Q^2 32        Eval and print. Due to leading "0b", eval as binary.

Golfe:

33 -> 32: Movido para adicionar antes de reverter para salvar uma cotação final.

32 -> 22: Q mod 2 ^ 32 usado em vez de máquinas complicadas. Combinou as duas cordas em uma.

Casos de teste:

$ cat rev_bits 
v_%"%032db0"vsc%Q^2 32

$ ./pyth.py rev_bits <<< -984802906
1704506019

$ ./pyth.py rev_bits <<< 486
1736441856

$ ./pyth.py rev_bits <<< 0
0
isaacg
fonte
Funciona com resultado como grandes 32 números tendo o bit mais à esquerda em 1? Nesse caso, ele deve gerar um número inteiro negativo.
edc65
@ edc65 Estou produzindo um número inteiro não assinado de 32 bits.
Isaacg
2

GNU dc, 27 bytes

0?[2~rssr2*+dlsz34>m]dsmx+p

Saída:

$ dc revbits.dc <<< 15
4026531840
$ dc revbits.dc <<< 255
4278190080
$ dc revbits.dc <<< 65535
4294901760
$ dc revbits.dc <<< 4294901760
65535
$ dc revbits.dc <<< 4278190080
255
$ dc revbits.dc <<< 4026531840
15
$ 

Bash + coreutils, 45 bytes

n=`dc -e2do32^n$1p`
dc -e2i`rev<<<${n: -32}`p

Saída:

$ ./revbits.sh 15
4026531840
$ ./revbits.sh 255
4278190080
$ ./revbits.sh 65535
4294901760
$ ./revbits.sh 4294901760
65535
$ ./revbits.sh 4278190080
255
$ ./revbits.sh 4026531840
15
$ 

Função C, 89 bytes

A mesma idéia que /codegolf//a/36289/11259 - usando os hacks de Stanford . Não vai ganhar o golfe, mas interessante, no entanto:

// 89 byte function:
i;r(v){for(i=1;i<32;i*=2)v=v>>i&(1L<<32)/((1<<i)+1)|(v&(1L<<32)/((1<<i)+1))<<i;return v;}

// Test program:
#include <stdio.h>

int main (int argc, char **argv)
{
    printf("r(0x0000000f) = 0x%08x\n", r(0x0000000f));
    printf("r(0x000000ff) = 0x%08x\n", r(0x000000ff));
    printf("r(0x0000ffff) = 0x%08x\n", r(0x0000ffff));
    printf("r(0xffffffff) = 0x%08x\n", r(0xffffffff));
    printf("r(0x0f0f0f0f) = 0x%08x\n", r(0x0f0f0f0f));
    printf("r(0xf0f0f0f0) = 0x%08x\n", r(0xf0f0f0f0));
}

Saída:

$ ./revbits 
r(0x0000000f) = 0xf0000000
r(0x000000ff) = 0xff000000
r(0x0000ffff) = 0xffff0000
r(0xffffffff) = 0xffffffff
r(0x0f0f0f0f) = 0xf0f0f0f0
r(0xf0f0f0f0) = 0x0f0f0f0f
$
Trauma Digital
fonte
2

Função Java, 64 caracteres.

 int r(int n){int r=0,i=32;for(;i-->0;n>>=1)r=r<<1|n&1;return r;}

Também deve funcionar em C.

Florian F
fonte
2

PHP, 46 bytes

Versões Online

for(;$i<32;)$t.=$argn>>$i++&1;echo bindec($t);

ou

<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Jörg Hülsermann
fonte
O substré desnecessário (-12 bytes). Você deve mencionar como executá-los.
Titus
11
@ Titus você já experimentou o testcase -984802906?
Jörg Hülsermann
11
Sua segunda versão pode ser aprimorada para corresponder à primeira:<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Christoph
@Christoph melhoria muito boa Obrigado
Jörg Hülsermann 15/17 '13:
1

JS 115

Bem, isso não parece nada bom: D

n=+prompt();alert(eval('0b'+(Array(33).join(0)+(n<0?n>>>0:n).toString(2)).slice(-32).split('').reverse().join('')))

O método do @Florian F em JS tem 53 bytes:

for(n=+prompt(r=0),i=32;i--;n>>=1)r=r<<1|n&1;alert(r)
bebe
fonte
11
A it may be a functionregra significa que você não precisa de alerta ou aviso
slebetman
1

C # 81 74

int R(int V){int l,r=l=0,i=1;for(;i>0;i*=2)r|=i*(1&V>>(31-l++));return r;}

Operações de bits que provavelmente podem ser feitas mais curtas em todas as linguagens de programação.

Basicamente, faça um loop através de todas as potências de 2 até um número inteiro máximo + 1 (que se transforma em uma potência de duas) e desde (2.147.483.647 + 1) = 0 Eu posso fazer um loop para 0. Deslocamento de bits Esquerda para a direita para mover o bit para o primeiro posição. O último bit no local 32 vai 31 etapas para a direita, o segundo último vai 30 etc. Portanto, usando o operador AND com 1, saberei se é 1 ou 0. Se for 1, adicionarei o valor atual de i ao resultado e devolver.

int R(int V)
{
    int l,r=l=0,i=1;
    for(;i>0;i*=2)
        r|=i*(1&(V>>(31-l++)));
    return r;
 }
WozzeC
fonte
Coisas pequenas, mas você pode inicializar iquando o declarar e salvar um byte removendo i++do loop for e, em vez de comparar o resultado de 1&...0, você pode remover a instrução if completamente e multiplicar ipelo resultado r|=i*(1&(V>>(31-l++)));
fornecido
Inteligente! Tive a sensação de que estava perdendo alguma coisa. Obrigado!
WozzeC
1

C # 142

using System;using System.Linq;int f(int n){return Convert.ToInt32(new string(Convert.ToString(n,2).PadLeft(32,'0').Reverse().ToArray()),2);}

Expandido

int f(int n)
{
    return Convert.ToInt32(
        new string(
            Convert.ToString(n, 2)
            .PadLeft(32, '0')
            .Reverse()
            .ToArray()), 2);
}
BenVlodgi
fonte
1

Python - 37

Semelhante à solução de @ isaacg.

f=lambda n:int(bin(n%2**32)[:1:-1],2)
cjfaure
fonte
1

C ++, 160

Esta não é a mais curta, no entanto, utiliza apenas 24 operações.
Retirado do livro Hacker's Delight.

Golfe:

typedef unsigned U;U R(U&x){U a=-1u/3,b=-1u/5,c=-1u/17,d=65280;x=(x&a)*2|(x/2)&a;x=(x&b)*4|(x/4)&b;x=(x&c)<<4|(x>>4)&c;x=(x<<24)|((x&d)<<8)|((x>>8)&d)|(x>>24);}

Ungolfed:

unsigned R(unsigned x) {
    x = (x & 0x55555555) <<  1 | (x >>  1) & 0x55555555; 
    x = (x & 0x33333333) <<  2 | (x >>  2) & 0x33333333; 
    x = (x & 0x0F0F0F0F) <<  4 | (x >>  4) & 0x0F0F0F0F; 
    x = (x << 24) | ((x & 0xFF00) << 8) | ((x >> 8) & 0xFF00) | (x >> 24); 
    return x; 
} 
Somnium
fonte
11
Esta é uma questão de código de golfe. Por favor, tente reduzir o número de caracteres em sua solução, não o número de operações.
FUZxxl
1

Haskell, 145 - sem operações bit a bit

A manipulação de bits me parece a antítese de Haskell, por isso evitei o uso de operadores bit a bit. O programa resultante certamente não é o menor concorrente, mas achei que o uso da matemática, em vez da manipulação de bits, era interessante pelo menos.

import Data.Tuple
import Data.List
f m=foldl1((+).(*2))$take 32$(unfoldr(\n->if n==0 then Nothing else Just$swap$divMod n 2)$mod m$2^32)++[0,0..]

Explicação

f m=foldl1((+).(*2))$take 32$(unfoldr(\n->if n==0 then Nothing else Just$swap$divMod n 2)$mod m$2^32)++[0,0..]
    |------5-------|---4----|--------------------------2---------------------------------|----1-----|---3----|
  1. usa módulo para trazer o resultado para a faixa de 32 bits
  2. constrói uma lista de 0s e1 s, bit menos significativo primeiro dividindo repetidamente por 2 e tomando o restante
  3. concatena uma lista infinita de 0 s até o final desta lista
  4. pega os 32 primeiros elementos da lista (esses dois últimos foram necessários para garantir que a lista tenha 32 bits.)
  5. converte uma lista de 0e 1em um número inteiro, assumindo que o bit mais significativo é o primeiro (duplicado e adicionado repetidamente).

Não tenho muita certeza do que constitui "a biblioteca padrão" em Haskell, por isso presumi que Data.Tuple e Data.List estavam OK (eles são bastante padrão).

Além disso, a saída é um sem assinatura inteiro de 32 bits desde a mudança que me custaria bytes: Eu estou discutindo isso em "omissões são jogo livre".

ballesta25
fonte
Biblioteca padrão: o que acompanha o idioma. Isso inclui cabeçalhos de sistema para C, as mais de 4000 classes e métodos em Java (a maioria é irrelevante).
Isiah Meadows
1

PHP, 46 41 bytes

experimentá-los online

while($i<32)$r=$r*2|$argn>>$i++&1;echo$r;

bit a bit ... mais ou menos. Executar como tubo comphp -nR '<code>' .

PHP, 46 bytes

while($i<32)$r|=($argn>>$i&1)<<31-$i++;echo$r;

uma solução bit a bit pura; correr como tubo com-nR .

PHP, 47 59 bytes

<?=bindec(str_pad(strrev(substr(decbin($argn),-32)),32,0));

outra abordagem integrada; salve em arquivo e execute como pipe com -F.

Titus
fonte
0

Perl - 60

$_=unpack"N",pack"B*",scalar reverse unpack"B32",pack"N",$_

+1 para o sinalizador p (deixe-me saber se estou contando isso errado).

Correr com:

echo 486 | perl -pe'$_=unpack"N",pack"B32",scalar reverse unpack"B32",pack"N",$_'
hmatt1
fonte
0

C ++ 69

int r(int n){int e=0,i=0;for(;i<32;i++)e|=((n>>i)&1)<<31-i;return e;}
rdans
fonte
@ beeb o que são esses e;i;? Declarações sem tipo não são um C ++ válido. Para variáveis ​​nem sequer é C. C.
Ruslan
@Ruslan eu não reconheci '++' no título, desculpe. (eu não concordo com a sua segunda declaração)
bebe
int r(int n){int e=0,i=0;for(;i<32;)e=e*2|1&n>>i++;return e;}61 bytes :)
Christoph
0

R, 45

f=function(x)packBits(intToBits(x)[32:1],"i")

Exemplos:

f(486)
# [1] 1736441856
f(-984802906)
# [1] 1704506019

Sempre apenas evite as respostas em Python. Essa maldita palavra-chave de função.

shadowtalker
fonte
0

Rubi, 43 41 bytes

def r(n)(0..31).inject(0){|a,b|a*2+n[b]}end

Em Ruby, o uso da notação de índice de colchete (foo [i]) retorna o bit no enésimo lugar.

--Editar--

A refatoração da injectfuncionalidade reduz alguns bytes

def r(n)z=0;32.times{|i|z=z*2+n[i]};z;end

marcus erronius
fonte
0

Perl5: 46

sub r{for(0..31){$a=$a*2|$_[0]&1;$_[0]>>=1}$a}

Nada chique. Ele muda a saída para a esquerda, copia lsb antes de mudar a fonte para a direita.

Sylwester
fonte
0

Clojure, 202 156 142

#(read-string (let [s (clojure.pprint/cl-format nil "~2r" %)](apply str (reverse (apply str (concat (repeat (- 32 (count s)) "0") s "r2"))))))
Bob Jarvis - Restabelecer Monica
fonte
0

Perl (37 + 1)

basicamente uma porta da solução C de Todd Lehman

perl -E '$t=<>;map$r=2*$r|1&$t>>$_,0..31;say$r'

gótico chinês do perl
fonte