Ordre des bits inversés des entiers 32 bits


21

Écrivez le code le plus court pour inverser l'ordre des bits d'un entier 32 bits.

Règles:

  1. L'entrée est supposée être un entier ou une chaîne équivalente valide si votre langue ne prend pas en charge les valeurs numériques (par exemple, Windows Batch).
  2. La sortie doit être un entier ou une chaîne équivalente valide si votre langue ne prend pas en charge les valeurs numériques (par exemple, Windows Batch).
  3. Bibliothèque standard uniquement.
  4. Il peut s'agir d'une fonction ou d'un programme complet.
  5. L'entrée peut provenir de stdinou comme argument de fonction.
  6. La sortie doit être soit stdoutou comme valeur retournée.
  7. Si votre langue a une fonction de bibliothèque intégrée ou standard qui le fait en une seule étape (par exemple rbitdans l'assemblage ARM), cela ne peut pas être utilisé.

Exemples:

Clé:

  1. décimal
    • binaire
    • (sens inverse)
    • binaire inversé
    • sortie décimale

Exemples:

  1. -90 (Exemple 8 bits pour démonstration)

    • 10100110b
    • (sens inverse)
    • 01100101b
    • 101
  2. 486

    • 00000000000000000000000111100110b
    • (sens inverse)
    • 01100111100000000000000000000000b
    • 1736441856
  3. -984802906

    • 11000101010011010001100110100110b
    • (sens inverse)
    • 01100101100110001011001010100011b
    • 1704506019

Remarque: les omissions sont un jeu gratuit. Si je ne l'ai pas dit et que ce n'est pas une des failles standard , alors c'est complètement autorisé.


Qu'entend-on par «omissions» dans «les omissions sont du jeu gratuit»?
Todd Lehman

1
Tout ce qui n'est pas explicitement indiqué dans les règles.
Isiah Meadows

Une table statique de 16 Go serait-elle prise en compte dans la durée du programme?
Hot Licks

@HotLicks Selon l'interprétation typique du programme, oui.
FUZxxl

langue qui ne prend en charge que les entrées 8 bits, pouvons-nous prendre l'entrée comme quatre nombres 8 bits?
Sparr

Réponses:


0

assemblage x86, 9 octets

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

Sous forme d' 33 C0 40 D1 E9 13 C0 73 FAoctets:, 9 octets.


C'est encore autant que ma solution si vous (a) obéissez à la convention d'appel cdecl et (b) revenez réellement de la fonction.
FUZxxl

@FUZxxl D'une manière ou d'une autre, je n'ai pas vu votre version. Vous avez parfaitement raison. Je réfléchissais __fastcallet je n'en avais pas ret.
Myria

24

Assemblage MMIX (28 octets)

Nombres 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

Cela s'assemble pour:

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

Comment ça marche?

L' MORinstruction effectue une multiplication matricielle sur deux quantités 64 bits utilisées comme deux matrices 8x8 de booléens. Un nombre booléen avec des chiffres abcdefghklmnopqr 2 est utilisé comme matrice comme ceci:

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

L' MORinstruction multiplie les matrices représentées par leurs arguments où la multiplication est andet l'addition est or. Il est:

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

et en plus:

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

qui est l'ordre inverse des bits du nombre d'origine.

Nombres de 32 bits

Si vous voulez juste l'inverse d'un nombre 32 bits au lieu d'un nombre 64 bits, vous pouvez utiliser cette méthode modifiée:

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

assemblé:

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

La première multiplication matricielle fonctionne essentiellement comme ceci:

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

l'octaoctet correspondant est celui #0000000001020408que nous chargeons dans les deux premières instructions. La deuxième multiplication ressemble à ceci:

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

L'octaoctet correspondant est celui #0102040810204080que nous créons à partir de la première matrice comme ceci:

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

La deuxième multiplication est comme d'habitude, le code résultant a la même longueur (28 octets).


1
c'est la première fois que j'entends parler d'instructions de multiplication matricielle sur un CPU
phuclv

@ LưuVĩnhPhúc: Pas une multiplication matricielle, mais VAX avait une instruction pour évaluer un polynôme .
nneonneo

1
@nneonneo L' POLYinstruction du VAX est fondamentalement une multiplication et une addition fusionnées avec une boucle intégrée. Des choses similaires existent également dans les architectures modernes (comme x86), mais elles n'ont généralement pas de boucle intégrée pour évaluer un polynôme entier à la fois.
FUZxxl

12

Assemblage 80386 ( 13 12 octets)

En tant que fonction dans la syntaxe AT&T en utilisant la convention d'appel 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

Cette fonction s'assemble à la séquence d'octets suivante:

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

Décomposé en instructions:

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    

Cela fonctionne comme ceci: dans chacune des 32 itérations de la boucle, l'argument, qui est situé à 4(%esp), est décalé vers la droite d'une position. Le dernier bit est implicitement décalé dans le drapeau de retenue. L' adcinstruction ajoute deux valeurs et ajoute la valeur de l'indicateur de report au résultat. Si vous ajoutez une valeur à elle-même, c'est-à-dire que %eaxvous la décalez effectivement vers la gauche d'une position. Cela constitue adc %eax,%eaxun moyen pratique de décaler vers la gauche %eaxd'une position tout en décalant le contenu du drapeau de report dans le bit de poids faible.

Je répète ce processus 32 fois pour que tout le contenu de 4(%esp)soit vidé %eax. Je n'initialise jamais explicitement %eaxcar son contenu précédent est déplacé pendant la boucle.


+1 Merci pour votre dernière phrase, c'est évident maintenant mais ça m'a manqué.
edc65

1
Je suis toujours heureux de voir des solutions d'assemblage ici :)
user1354557

8

C,    63    52   48

Version originale:

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

Version mise à jour (avec des modifications suggérées par Allbeert , es1024 et Dennis ):

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

Remarque: Étant donné que la deuxième version omet le paramètre r=0, le code suppose que an intvaut 32 bits. Si cette hypothèse est fausse, la fonction produira très probablement un résultat incorrect, selon l'état initial rlors de l'entrée dans la fonction.


Version finale (avec d'autres modifications suggérées par Dennis et Alchymist ):

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

Remarque: Cela place la déclaration des variables de travail ret idans la liste des paramètres. Les paramètres sont les suivants: nest le nombre à inverser en bits. ret isont des variables de travail qui doivent être passées à 0.


1
Vous pouvez supprimer le inttype de fonction et également changer return rpour quelque chose comme, i=rcar la plupart des compilateurs C ont tendance à laisser le résultat de la dernière opération dans le registre de retour. Cela a fonctionné sur gcc et cl pour moi.
Allbeert

1
Vous pouvez raser 4 autres octets en utilisant r(n){...}au lieu der(int n){...}
es1024

2
@FUZxxl, vous ne pouvez pas déposer le fichier intà int r=0,i=32;moins de le déplacer hors du corps de la fonction.
es1024

1
@FUZxxl: Je ne devrais pas commenter quand je suis fatigué ... Le décalage et la division arithmétiques ne sont pas équivalents; ce dernier arrondit vers zéro, tandis que les premiers arrondissent vers l'infini négatif. -1 >> 1est -1pour AS et 2**31 - 1pour LS, tandis que -1 / 2est 0.
Dennis

1
@Todd: Une raison pour laquelle vous n'avez pas défini ret icomme arguments? Économiserait trois octets de plus ...
Dennis

5

Julia 0,2, 33 octets

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

Fait à quoi ça ressemble.

bitsvous donne la représentation des bits (en respectant le complément à deux). parseintne se soucie pas du complément à deux, mais renvoie un entier 32 bits, donc le complément à deux est simplement géré par débordement.

Selon les changelogs, la détection de débordement a été ajoutée parseintdans Julia 0.3, donc cela pourrait ne plus fonctionner.


5
C'est du code de production, pas du code golfé! xD Je suppose que Julia est juste géniale.
cjfaure

4

Python 2, 50

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

Généralement la même que ma solution Pyth. Prenez le mod d'entrée 2 ** 32, convertissez en binaire rembourré 32 bits, inversez, convertissez la piqûre binaire en décimal et imprimez.


4

CJam, 15 octets

li4H#+2bW%32<2b

Essayez-le en ligne.

Joker "jeu gratuit" utilisé: La sortie sera toujours un entier non signé .

Cas de test

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

Comment ça marche

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. ";

4

JavaScript (E6) 37 39 40 50

Fonction, entrée de numéro et retour d'un numéro inversé. L'algorithme le plus basique peut probablement être joué plus avec une astuce intelligente.

Modifier la récursivité au lieu de la boucle

Modifier 2 Suivant la suggestion @bebe k*2au lieu dek<<1

Edit 3 Quelque chose que j'avais manqué du tout: c'est une boucle complète de 32 bits, pas besoin d'initialiser k. Merci @FUZxxl

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

C'était

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

Testez dans la console FireFox, testez en utilisant des nombres dans OP et quelques autres nombres aléatoires de 16 et 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))))

Exemple de sortie de test

        -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

b=k=0,R=v=>b++<32?R(v>>1,k+=k+(v&1)):kà usage unique et R=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):kest réutilisable
bebe

@bebe :( Je révisais ma réponse en utilisant la récursivité et j'ai tout perdu pour lire votre commentaire ...
edc65

2
vous êtes à 38 octets si k<<1devient k*2et v>>1devient v/2. cela a fonctionné pour 486. je ne sais pas d'autres cas de test
bebe

1
@bebe v / 2 ne fonctionnera pas pour les nombres négatifs. 486/512 == 0.9 ... et 486 >> 9 == 0, trunc c'est pareil. Mais -90/128 == -0,7 ... et -90 >> 7 == - 1
edc65

4

Assemblage x86, 10 octets

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

Cela suppose une entrée dans eax, une sortie dans edx. (En outre, à la sortie, eax est nul et CF et ZF sont définis, si quelqu'un s'en soucie).

Au lieu d'un compteur, un 1 supplémentaire est inséré au début comme marqueur de fin de données


Cela a en fait la même taille que ma solution, qui est plus grande de trois octets. Si vous ajoutez l' retinstruction de retour de la fonction et implémentez cdecl (c'est- rcr %eaxà- dire changez vers rcr 4(%esp)et rcl %edxvers rcl %eax), vous vous retrouvez avec un octet supplémentaire pour le retet deux autres octets pour la référence mémoire. Pourtant, une belle solution.
FUZxxl

3

J ( 17 15 13 octets)

_32#.@|.@{.#:

Voici une définition explicite pour expliquer ce qu'il fait:

3 : '#. |. _32 {. #: y'
  1. #: yreprésente yun nombre de base 2 en utilisant autant d'emplacements que nécessaire.
  2. x {. yprend |x(magnitude de x) les éléments de y, de l'avant si xest positif, de l'arrière si xest négatif. Si nous prenons plus d'articles que présents, le résultat est rempli de zéros. _32 {. #: ytamponne efficacement #: yà 32 bits.
  3. |. yflips y, i. inverse l'ordre des éléments dans y.
  4. #. y interprète ycomme un nombre de base 2.


2

Python - 89

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

Python représente simplement les nombres binaires négatifs -0b{positive_number}. Donc, pour faire face à cela, complétez les nombres négatifs puis XOR avec tous les 1.

Après cela, créez la représentation sous forme de chaîne de l'entier en fonction du format {:032b}qui fournit la représentation 32 bits du nombre. Enfin, inversez la chaîne et retournez-la en entier.

MODIFIER

Merci à @Martin Büttner d' avoir signalé un problème de complément à deux. Si nse termine par un 1, alors par un complément à deux, la version inversée serait négative.

Heureusement, comme expliqué ci-dessus, Python aime les nombres binaires négatifs d'une manière assez simple. Heureusement aussi, la intfonction de Python autorise les caractères de signe facultatifs dans son premier argument.

Alors maintenant, ajoutez un signe moins si nest impair pour satisfaire le complément à deux.


@ MartinBüttner Merci. J'ai raté cette possibilité au début. Le nouveau code gère mieux le complément à deux.
BeetDemGuise

2
Vous pouvez jouer au golf un peu plus: ['','-'][n%2]c'est '-'*(n%2).
Justin

2

Pyth , 33 32 22

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

Explication:

                 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.

Golfs:

33 -> 32: Déplacer l'ajout à avant d'inverser pour enregistrer un devis final.

32 -> 22: Q mod 2 ^ 32 d'occasion au lieu de machines compliquées. Combiné les deux chaînes en une seule.

Cas de test:

$ 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

Est-ce que cela fonctionne avec comme résultat un grand nombre de 32 ayant le bit le plus à gauche à 1? Dans ce cas, il doit sortir un entier négatif.
edc65

@ edc65 J'émets un entier non signé 32 bits.
isaacg

2

GNU dc, 27 octets

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

Sortie:

$ 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 octets

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

Sortie:

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

Fonction C, 89 octets

Même idée que /codegolf//a/36289/11259 - en utilisant les hacks twiddling de Stanford . Ne va pas gagner le golf, mais intéressant quand même:

// 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));
}

Sortie:

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

2

Fonction Java, 64 caractères.

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

Devrait également fonctionner en C.


2

PHP, 46 octets

Versions en ligne

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

ou

<?=bindec(strrev(sprintf("%064b",$argn<<32)));

Le substrest inutile (-12 octets). Vous devez mentionner comment les exécuter.
Titus

1
@Titus, avez-vous essayé le testcase -984802906?
Jörg Hülsermann

1
Votre deuxième version peut être améliorée pour correspondre à la première:<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Christoph

@Christoph très belle amélioration Merci
Jörg Hülsermann

1

JS 115

Eh bien, ça n'a pas l'air bien du tout: D

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

La méthode de @Florian F dans JS est longue de 53 octets:

for(n=+prompt(r=0),i=32;i--;n>>=1)r=r<<1|n&1;alert(r)

1
La it may be a functionrègle signifie que vous n'avez pas besoin de l'alerte ou de l'invite
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;}

Les opérations sur les bits qui sont très probablement plus courtes dans tous les langages de programmation.

Fondamentalement, parcourez toutes les puissances de 2 jusqu'au maximum entier + 1 (qui se transforme en une puissance de deux) et depuis (2 147 483 647 + 1) = 0, je peux boucler sur 0. Décalage de bits de gauche à droite pour déplacer le bit dans le premier position. Le dernier bit à la place 32 va 31 pas à droite, l'avant-dernier va 30 etc. Donc, en utilisant l'opérateur AND avec 1, je saurai si c'est 1 ou 0. Si c'est 1, j'ajouterai la valeur i actuelle au résultat et rends le.

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

De petites choses, mais vous pouvez initialiser ilorsque vous le déclarez et enregistrer un octet en le supprimant i++de la boucle for, et au lieu de comparer le résultat de 1&...avec 0, vous pouvez supprimer complètement l'instruction if et multiplier ipar le résultat donnant r|=i*(1&(V>>(31-l++)));à l'intérieur de la boucle
VisualMelon

Intelligent! J'avais le sentiment qu'il me manquait quelque chose. Merci!
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);}

Étendu

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

1

Python - 37

Similaire à la solution de @ isaacg.

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

1

C ++, 160

Ce n'est pas le plus court, mais il n'utilise que 24 opérations.
Tiré du livre Hacker's Delight.

Golfé:

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);}

Non golfé:

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; 
} 

1
Ceci est une question de code de golf. Essayez de réduire le nombre de caractères dans votre solution, pas le nombre d'opérations.
FUZxxl

1

Haskell, 145 - aucune opération au niveau du bit

Le bit-twiddling me semble être l'antithèse de Haskell, j'ai donc évité toute utilisation d'opérateurs au niveau du bit. Le programme résultant n'est certainement pas le candidat le plus court, mais je pensais que l'utilisation des mathématiques au lieu du bit-twiddling était intéressante au moins.

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..]

Explication

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. utilise modulo pour amener le résultat dans une plage de 32 bits
  2. construit une liste de 0s et 1s, bit le moins significatif en premier en divisant à plusieurs reprises par 2 et en prenant le reste
  3. concatène une liste infinie de 0s à la fin de cette liste
  4. saisit les 32 premiers éléments de la liste (Ces deux derniers étaient nécessaires pour garantir que la liste est en fait de 32 bits.)
  5. convertit une liste de 0et 1en un entier en supposant que le bit le plus significatif est le premier (répété double et additionné).

Je ne sais pas trop ce qui constitue "la bibliothèque standard" dans Haskell, j'ai donc supposé que Data.Tuple et Data.List étaient OK (ils sont assez standard).

En outre, la sortie est un entier 32 bits non signé, car une modification qui me coûterait des octets: je dis cela sous "les omissions sont du jeu gratuit".


Bibliothèque standard: ce qui accompagne la langue. Cela inclut les en-têtes système pour C, les 4000+ classes et méthodes de Java (la plupart ne sont pas pertinentes).
Isiah Meadows

1

PHP, 46 41 octets

essayez-les en ligne

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

au niveau du bit ... plus ou moins. Exécuter en tant que tuyau avec php -nR '<code>'.

PHP, 46 octets

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

une solution pure au niveau du bit; courir comme tuyau avec -nR.

PHP, 47 59 octets

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

une autre approche intégrée; enregistrer dans un fichier et exécuter en tant que pipe avec -F.


0

Perl - 60

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

+1 pour le drapeau p (faites-moi savoir si je compte mal).

Courir avec:

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

0

C ++ 69

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

@bebe qu'est-ce que c'est e;i;? Les déclarations sans type ne sont pas un C ++ valide. Pour les variables, ce n'est même pas valide C.
Ruslan

@Ruslan, je n'ai pas reconnu '++' dans le titre, désolé. (je ne serais pas d'accord avec votre deuxième déclaration)
bebe

int r(int n){int e=0,i=0;for(;i<32;)e=e*2|1&n>>i++;return e;}61 octets :)
Christoph

0

R, 45

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

Exemples:

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

Toujours juste timide des réponses Python. Ce foutu mot-clé de fonction.


0

Rubis, 43 41 octets

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

Dans Ruby, l'utilisation de la notation d'index de parenthèse (foo [i]) renvoie le bit à la nième place.

--Éditer--

La refactorisation de la injectfonctionnalité réduit de quelques octets

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


0

Perl5: 46

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

Rien d'extraordinaire. Il décale la sortie vers la gauche, copie lsb avant de décaler la source vers la droite.


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"))))))

0

Perl (37 + 1)

essentiellement un portage de la solution C par Todd Lehman

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.