Umgekehrte Bitreihenfolge von 32-Bit-Ganzzahlen


21

Schreiben Sie den kürzesten Code, um die Bitreihenfolge einer 32-Bit-Ganzzahl umzukehren.

Regeln:

  1. Die Eingabe wird als gültige Ganzzahl oder Zeichenfolge angenommen, wenn Ihre Sprache keine numerischen Werte unterstützt (z. B. Windows Batch).
  2. Die Ausgabe muss eine gültige Ganzzahl oder eine Zeichenfolge sein, wenn Ihre Sprache keine numerischen Werte unterstützt (z. B. Windows Batch).
  3. Nur Standardbibliothek.
  4. Dies kann eine Funktion oder ein vollständiges Programm sein.
  5. Die Eingabe kann entweder von stdinoder als Funktionsargument erfolgen.
  6. Die Ausgabe muss entweder stdoutoder als Rückgabewert erfolgen.
  7. Wenn Ihre Sprache über eine integrierte oder standardmäßige Bibliotheksfunktion verfügt, die dies in einem Schritt erledigt (z. B. rbitin der ARM-Assembly), kann diese nicht verwendet werden.

Beispiele:

Schlüssel:

  1. Dezimal
    • binär
    • (umkehren)
    • umgekehrt binär
    • Dezimalausgabe

Beispiele:

  1. -90 (8-Bit-Beispiel zur Demonstration)

    • 10100110b
    • (umkehren)
    • 01100101b
    • 101
  2. 486

    • 00000000000000000000000111100110b
    • (umkehren)
    • 01100111100000000000000000000000b
    • 1736441856
  3. -984802906

    • 11000101010011010001100110100110b
    • (umkehren)
    • 01100101100110001011001010100011b
    • 1704506019

Hinweis: Auslassungen sind freies Spiel. Wenn ich es nicht gesagt habe und es keine der Standardlücken ist , dann ist es völlig erlaubt.


Was ist mit "Auslassungen" in "Auslassungen sind freies Spiel" gemeint?
Todd Lehman

1
Alles, was nicht ausdrücklich in den Regeln angegeben ist.
Isiah Meadows

Würde eine statische Tabelle mit 16 GB als Teil der Programmlänge gezählt?
Hot Licks

@HotLicks Nach der typischen Interpretation des Programms ja.
FUZxxl

Sprache, die nur 8-Bit-Eingaben unterstützt. Können wir Eingaben als vier 8-Bit-Zahlen annehmen?
Sparr

Antworten:


0

x86-Assembly, 9 Byte

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

In Byte-Form: 33 C0 40 D1 E9 13 C0 73 FA9 Byte.


Das ist wieder genau so lange wie meine Lösung, wenn Sie (a) die cdecl-Aufrufkonvention befolgen und (b) tatsächlich von der Funktion zurückkehren.
FUZxxl

@FUZxxl Irgendwie habe ich deine Version nicht gesehen. Sie haben völlig recht. Ich habe nachgedacht __fastcallund hatte das nicht ret.
Myria

24

MMIX-Assembly (28 Byte)

64-Bit-Zahlen

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

Dies setzt sich zusammen zu:

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

Wie funktioniert es?

Der MORBefehl führt eine Matrixmultiplikation für zwei 64-Bit-Größen durch, die als zwei 8 × 8-Matrizen von Booleschen Werten verwendet werden. Eine boolesche Zahl mit den Ziffern abcdefghklmnopqr 2 wird als Matrix wie folgt verwendet:

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

Der MORBefehl multipliziert die durch ihre Argumente dargestellten Matrizen, wobei Multiplikation andund Addition vorliegen or. Es ist:

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

und außerdem:

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

Dies ist die umgekehrte Reihenfolge der Bits der ursprünglichen Nummer.

32-Bit-Nummern

Wenn Sie nur die Umkehrung einer 32-Bit-Zahl anstelle einer 64-Bit-Zahl wünschen, können Sie diese modifizierte Methode verwenden:

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

gebaut:

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

Die erste Matrixmultiplikation funktioniert grundsätzlich so:

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

Das entsprechende Oktabyte wird #0000000001020408in den ersten beiden Anweisungen geladen. Die zweite Multiplikation sieht folgendermaßen aus:

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

Das entsprechende Oktabyte #0102040810204080erstellen wir aus der ersten Matrix wie folgt :

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

Die zweite Multiplikation erfolgt wie gewohnt, der resultierende Code hat die gleiche Länge (28 Bytes).


1
Es ist das erste Mal, dass ich von Matrixmultiplikationsanweisungen auf einer CPU
höre

@ LưuVĩnhPhúc: Keine Matrixmultiplikation, aber VAX hatte die Anweisung, ein Polynom auszuwerten .
Nneonneo

1
@nneonneo Der POLYBefehl des VAX ist im Grunde genommen ein verschmolzenes Multiplizieren und Addieren mit einer eingebauten Schleife. Ähnliche Dinge gibt es auch in modernen Architekturen (wie x86), aber normalerweise haben sie keine eingebaute Schleife, um ein ganzes Polynom auf einmal auszuwerten.
FUZxxl

12

80386-Assembly ( 13 bis 12 Byte)

Als Funktion in der AT & T-Syntax unter Verwendung der Aufrufkonvention 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

Diese Funktion setzt sich aus der folgenden Bytefolge zusammen:

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

Aufgeschlüsselt in Anweisungen:

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    

Das funktioniert so: In jeder der 32 Iterationen der Schleife wird das Argument, das sich an 4(%esp)befindet, um eine Position nach rechts verschoben. Das letzte Bit wird implizit in das Übertragsflag verschoben. Der adcBefehl addiert zwei Werte und addiert den Wert des Übertrag-Flags zum Ergebnis. Wenn Sie einen Wert zu sich selbst hinzufügen, dh %eax, Sie verschieben ihn effektiv um eine Position nach links. Dies ist adc %eax,%eaxeine bequeme Möglichkeit, %eaxum eine Position nach links zu verschieben, während der Inhalt des Übertragsflags in das niederwertige Bit verschoben wird.

Ich wiederhole diesen Vorgang 32 Mal, damit der gesamte Inhalt von 4(%esp)in entleert wird %eax. Ich initialisiere nie explizit, %eaxda der vorherige Inhalt während der Schleife verschoben wird.


+1 Danke für deinen letzten Satz. Es ist jetzt offensichtlich, aber das habe ich verpasst.
edc65

1
Ich freue mich immer, Montagelösungen hier zu sehen :)
user1354557

8

C    63    52   48

Originalfassung:

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

Aktualisierte Version (mit Änderungen, die von Allbeert , es1024 und Dennis vorgeschlagen wurden ):

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

Hinweis: Da in der zweiten Version die Einstellung weggelassen wird r=0, wird im Code von int32 Bit ausgegangen . Wenn diese Annahme falsch ist, wird die Funktion höchstwahrscheinlich ein falsches Ergebnis liefern, abhängig vom Anfangszustand des rEintritts in die Funktion.


Endgültige Fassung (mit weiteren Änderungsvorschlägen von Dennis und Alchymist ):

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

Hinweis: Dadurch wird die Deklaration der Arbeitsvariablen rund iin die Parameterliste übernommen. Die Parameter lauten wie folgt: nist die Zahl, die bitweise umgekehrt werden soll. rund isind Arbeitsvariablen, die als 0 übergeben werden müssen.


1
Sie können den intFunktionstyp entfernen und auch return rzu so etwas wie wechseln , i=rda die meisten C-Compiler dazu neigen, das Ergebnis der letzten Operation im Rückgaberegister zu belassen. Es funktionierte auf gcc und cl für mich.
Allbeert

1
Sie können weitere 4 Bytes r(n){...}r(int n){...}
abschneiden,

2
@FUZxxl Sie können das intIn int r=0,i=32;nicht ablegen, es sei denn, Sie verschieben sie aus dem Funktionskörper.
es1024

1
@FUZxxl: Sollte nicht kommentieren, wenn ich müde bin ... Arithmetische Verschiebung und Division sind nicht gleichbedeutend; der letztere rundet in Richtung Null, während der erste in Richtung negativer Unendlichkeit rundet. -1 >> 1ist -1für AS und 2**31 - 1für LS, während -1 / 2ist 0.
Dennis

1
@Todd: Hast du irgendeinen Grund nicht definiert rund ials Argumente? Würde drei weitere Bytes sparen ...
Dennis

5

Julia 0,2, 33 Bytes

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

Tut, wie es aussieht.

bitsgibt Ihnen die Bit-Darstellung (unter Berücksichtigung des Zweierkomplements). parseintkümmert sich nicht um das Zweierkomplement, sondern gibt eine 32-Bit-Ganzzahl zurück, sodass das Zweierkomplement einfach durch Überlauf behandelt wird.

Gemäß den Änderungsprotokollen wurde parseintin Julia 0.3 die Überlauferkennung hinzugefügt , sodass dies möglicherweise nicht mehr funktioniert.


5
Dies ist der Seriencode, nicht der Golfcode! xD Ich denke Julia ist einfach großartig.
cjfaure

4

Python 2, 50

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

Im Großen und Ganzen das Gleiche wie meine Pyth-Lösung. Nehmen Sie den Eingangs-Mod 2 ** 32, konvertieren Sie ihn in eine 32-Bit-Binärdatei, kehren Sie ihn um, konvertieren Sie den Binärstich zurück in eine Dezimalzahl und drucken Sie ihn aus.


4

CJam, 15 Bytes

li4H#+2bW%32<2b

Probieren Sie es online aus.

Verwendeter Joker "Freies Spiel": Die Ausgabe wird immer ein ganze Zahl ohne Vorzeichen.

Testfälle

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

Wie es funktioniert

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

Funktion, Zahleneingabe und Rückgabe der umgekehrten Zahl. Die meisten grundlegenden Algorithmen lassen sich wahrscheinlich mit einem cleveren Trick besser spielen.

Rekursion statt Schleife bearbeiten

Bearbeiten Sie 2 nach @bebe Vorschlag k*2stattk<<1

Edit 3 Etwas, das ich überhaupt übersehen hatte: Es ist eine vollständige 32-Bit-Schleife, k muss nicht initialisiert werden. Danke @FUZxxl

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

Es war

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

Test Testen Sie in der FireFox-Konsole die Verwendung von Zahlen in OP und einigen weiteren zufälligen 16- und 32-Bit-Zahlen

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

Beispiel für eine Testausgabe

        -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)):kfür den einmaligen Gebrauch und R=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):kist wiederverwendbar
bebe

@bebe :( Ich überarbeitete meine Antwort mit Rekursion und verlor alles, um Ihren Kommentar zu lesen ...
edc65

2
Sie sind bei 38 Bytes, wenn k<<1wird k*2und v>>1wird v/2. es funktionierte für 486. i über andere Testfälle nicht wissen
bebe

1
@bebe v / 2 funktioniert nicht für negative Zahlen. 486/512 == 0,9 ... und 486 >> 9 == 0, abgeschnitten ist es dasselbe. Aber -90/128 == -0,7 ... und -90 >> 7 == - 1
edc65

4

x86-Assemply, 10 Byte

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

Dies setzt die Eingabe in eax und die Ausgabe in edx voraus. (Außerdem ist am Ausgang eax Null und CF und ZF werden gesetzt, wenn es jemanden interessiert).

Anstelle eines Zählers wird am Anfang eine zusätzliche 1 als Datenendemarker eingefügt


Das hat eigentlich die gleiche Größe wie meine Lösung, die drei Bytes größer ist. Wenn Sie die retAnweisung hinzufügen , von der Funktion zurückzukehren und cdecl zu implementieren (dh rcr %eaxzu rcr 4(%esp)und rcl %edxzu ändern rcl %eax), erhalten Sie ein zusätzliches Byte für die retund zwei weitere Bytes für die Speicherreferenz. Trotzdem eine schöne Lösung.
FUZxxl

3

J ( 17 15 13 Bytes)

_32#.@|.@{.#:

Hier ist eine explizite Definition, um zu erklären, was es tut:

3 : '#. |. _32 {. #: y'
  1. #: yStellt yals Basis 2 eine Zahl dar, die so viele Stellen wie nötig verwendet.
  2. x {. yNimmt |x(Größe von x) Elementen von yvorne, wenn xpositiv, von hinten, wenn xnegativ. Wenn wir mehr Elemente als vorhanden nehmen, wird das Ergebnis mit Nullen aufgefüllt. _32 {. #: yFüllt effektiv #: yauf 32 Bit auf.
  3. |. yflippt y, ich. kehrt die Reihenfolge der Elemente in um y.
  4. #. y interpretiert yals Basis-2-Zahl.


2

Python - 89

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

Python repräsentiert negative Binärzahlen so einfach -0b{positive_number}. Ergänzen Sie negative Zahlen und dann XOR mit allen Einsen, um damit umzugehen.

Erstellen Sie anschließend die Zeichenfolgendarstellung der Ganzzahl basierend auf dem Format {:032b}, das die 32-Bit-Darstellung der Zahl bereitstellt. Kehren Sie schließlich die Zeichenfolge um und wandeln Sie sie wieder in eine Ganzzahl um.

BEARBEITEN

Vielen Dank an @Martin Büttner für den Hinweis auf ein Zweierkomplement. Wenn nmit einer 1 endet, dann wäre die umgekehrte Version mit dem Zweierkomplement negativ.

Glücklicherweise mag Python, wie oben erklärt, negative Binärzahlen auf ziemlich einfache Weise. Zum Glück erlaubt Pythons intFunktion im ersten Argument optionale Zeichen .

Fügen Sie nun ein Minuszeichen hinzu, wenn nungerade ist, um das Zweierkomplement zu erfüllen.


@ MartinBüttner Danke. Diese Möglichkeit habe ich zunächst verpasst. Der neue Code handhabt Zweierkomplemente besser.
BeetDemGuise

2
Das kann man ein bisschen mehr golfen: ['','-'][n%2]ist '-'*(n%2).
Justin

2

Pyth , 33 32 22

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

Erläuterung:

                 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.

Golfplätze:

33 -> 32: Add to vor dem Umkehren verschoben, um ein Endzitat zu speichern.

32 -> 22: Q mod 2 ^ 32 anstelle von komplizierten Maschinen verwendet. Kombiniert beide Saiten zu einer.

Testfälle:

$ 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

Funktioniert es mit Ergebnissen wie großen 32-Zahlen, bei denen das Bit ganz links bei 1 liegt? In diesem Fall sollte eine negative Ganzzahl ausgegeben werden.
Edc65

@ edc65 Ich gebe eine 32-Bit-Ganzzahl ohne Vorzeichen aus.
Isaacg

2

GNU DC, 27 Bytes

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

Ausgabe:

$ 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

Ausgabe:

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

C-Funktion, 89 Bytes

Dieselbe Idee wie /codegolf//a/36289/11259 - unter Verwendung der Stanford-Bit-Twiddling-Hacks . Das Golfen nicht gewinnen, aber trotzdem interessant:

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

Ausgabe:

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

2

Java-Funktion, 64 Zeichen.

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

Sollte auch in C funktionieren.


2

PHP, 46 Bytes

Online-Versionen

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

oder

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

Das substrist unnötig (-12 Bytes). Sie sollten erwähnen, wie man sie laufen lässt.
Titus

1
@Titus hast du den Testfall ausprobiert -984802906?
Jörg Hülsermann

1
Ihre zweite Version kann verbessert werden, um der ersten zu entsprechen:<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Christoph

@Christoph sehr schöne Verbesserung Vielen Dank
Jörg Hülsermann

1

JS 115

Nun, das sieht überhaupt nicht gut aus: D

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

Die Methode von @Florian F in JS ist 53 Byte lang:

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

1
Die it may be a functionRegel besagt, dass Sie keine Warnung oder Aufforderung benötigen
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;}

Bitoperationen, die wahrscheinlich in allen Programmiersprachen kürzer ausgeführt werden können.

Grundsätzlich durchlaufen Sie alle Potenzen von 2 bis zu einer Ganzzahl von maximal + 1 (was zu einer Zweierpotenz wird) und da (2.147.483.647 + 1) = 0, kann ich eine Schleife auf 0 durchführen. Bitverschiebung von links nach rechts, um das Bit in die erste zu verschieben Position. Das letzte Bit an Platz 32 geht 31 Schritte nach rechts, das vorletzte geht 30 usw. Wenn Sie also den AND-Operator mit 1 verwenden, weiß ich, ob es 1 oder 0 ist. Wenn es 1 ist, addiere ich den aktuellen i-Wert zum Ergebnis und Gib es zurück.

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

Kleine Dinge, aber Sie können initialisieren, iwenn Sie es deklarieren, und ein Byte speichern, indem Sie es i++aus der for-Schleife entfernen. Anstatt das Ergebnis von 1&...mit 0 zu vergleichen, können Sie die if-Anweisung ganz entfernen und imit dem Ergebnis multiplizieren, das r|=i*(1&(V>>(31-l++)));in der Schleife
angezeigt

Klug! Ich hatte das Gefühl, etwas zu vermissen. Vielen Dank!
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);}

Erweitert

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

1

Python - 37

Ähnlich wie bei @ isaacg's Lösung.

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

1

C ++, 160

Dies ist nicht die kürzeste, verwendet jedoch nur 24 Operationen.
Entnommen aus Hackers Delight-Buch.

Golf gespielt:

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

1
Dies ist eine Code Golf Frage. Bitte versuchen Sie, die Anzahl der Zeichen in Ihrer Lösung zu reduzieren, nicht die Anzahl der Operationen.
FUZxxl

1

Haskell, 145 - keine bitweisen Operationen

Bit-Twiddling scheint mir das Gegenteil von Haskell zu sein, daher habe ich die Verwendung bitweiser Operatoren vermieden. Das resultierende Programm ist sicherlich nicht der kürzeste Teilnehmer, aber ich fand die Verwendung von Mathematik anstelle von Bit-Twiddling zumindest interessant.

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

Erläuterung

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. verwendet Modulo, um das Ergebnis in den 32-Bit-Bereich zu bringen
  2. erstellt eine Liste von 0 s und1 s, dem niedrigstwertigen Bit, indem es wiederholt durch 2 dividiert und den Rest aufnimmt
  3. verkettet eine unendliche Liste von 0 s an das Ende dieser Liste
  4. greift nach den ersten 32 Elementen der Liste (Die letzten beiden wurden benötigt, um sicherzustellen, dass die Liste tatsächlich 32 Bit lang ist.)
  5. wandelt eine Liste von 0und 1in eine ganze Zahl , die unter der Annahme , am meisten signifikante Bit zuerst (wiederholte Doppel und ADD).

Ich bin nicht ganz sicher, was "die Standardbibliothek" in Haskell ausmacht, also nahm ich an, dass Data.Tuple und Data.List in Ordnung waren (sie sind ziemlich Standard).

Die Ausgabe ist auch eine vorzeichenlose 32-Bit-Ganzzahl, da Änderungen, die mich Byte kosten würden: Ich argumentiere dies unter "Auslassungen sind freies Spiel".


Standardbibliothek: Was wird mit der Sprache geliefert? Dies schließt Systemheader für C, die über 4000 Klassen und Methoden in Java ein (die meisten sind irrelevant).
Isiah Meadows

1

PHP, 46 41 Bytes

Probiere sie online aus

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

bitweise ... mehr oder weniger. Als Rohr mit laufen lassen php -nR '<code>'.

PHP, 46 Bytes

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

eine reine bitweise Lösung; als Pfeife mit laufen-nR .

PHP, 47 59 Bytes

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

ein weiterer integrierter Ansatz; In Datei speichern und als Pipe mit ausführen -F.


0

Perl - 60

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

+1 für das p-Flag (lass es mich wissen, wenn ich das falsch zähle).

Laufen mit:

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 was sind das e;i;? Deklarationen ohne Typ sind kein gültiges C ++. Für Variablen ist es nicht einmal gültig C.
Ruslan

@ Ruslan Ich habe '++' im Titel nicht erkannt, sorry. (Ich würde Ihrer zweiten Aussage nicht zustimmen.)
Sei

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

Beispiele:

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

Immer nur schüchtern von den Python-Antworten. Das verdammte Funktionsschlüsselwort.


0

Rubin, 43 41 Bytes

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

In Ruby gibt die Verwendung der Indexnotation in Klammern (foo [i]) das Bit an der n-ten Stelle zurück.

--Bearbeiten--

Durch das Refactoring der injectFunktionalität werden einige Bytes gespart

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}

Nichts Außergewöhnliches. Die Ausgabe wird nach links verschoben. Kopieren Sie lsb, bevor Sie die Quelle nach rechts verschieben.



0

Perl (37 + 1)

Im Grunde genommen ein Port der C-Lösung von Todd Lehman

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.