Порядок зворотного розряду 32-бітних цілих чисел


21

Напишіть найкоротший код, щоб змінити порядок бітів 32-бітного цілого числа.

Правила:

  1. Введення вважається дійсним цілим чи строковим еквівалентом, якщо ваша мова не підтримує числових значень (наприклад, Пакет Windows).
  2. Вихід повинен бути дійсним цілим чи строковим еквівалентом, якщо ваша мова не підтримує числових значень (наприклад, Пакет Windows).
  3. Лише стандартна бібліотека
  4. Це може бути функція або повна програма.
  5. Введення може бути або stdinаргументом функції, або як функція.
  6. Вихідні дані повинні бути stdoutабо як повернене значення.
  7. Якщо у вашій мові є вбудована або стандартна бібліотечна функція, яка робить це за один крок (наприклад, rbitпри складанні ARM), її неможливо використовувати.

Приклади:

Ключ:

  1. десятковий
    • двійкові
    • (реверс)
    • зворотний двійковий
    • десятковий вихід

Приклади:

  1. -90 (8-бітний приклад для демонстрації)

    • 10100110b
    • (реверс)
    • 01100101b
    • 101
  2. 486

    • 00000000000000000000000111100110b
    • (реверс)
    • 01100111100000000000000000000000b
    • 1736441856
  3. -984802906

    • 11000101010011010001100110100110b
    • (реверс)
    • 01100101100110001011001010100011b
    • 1704506019

Примітка: Опущення - безкоштовна гра. Якщо я цього не сказав, і це не одна із стандартних лазів , то це повністю дозволено.


Що означає "пропуски" у "упущення - безкоштовна гра"?
Тодд Леман

1
Все, що прямо не вказано в правилах.
Ісія Медоуз

Чи вважатиметься статичною таблицею 16 Гб частиною тривалості програми?
Гарячі лизи

@HotLicks Відповідно до типової інтерпретації програми, так.
FUZxxl

мовою, яка підтримує лише 8-бітні входи, чи можемо ми приймати введення як чотири 8-бітні числа?
Спарр

Відповіді:


0

x86 збірка, 9 байт

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

У байтовій формі:, 33 C0 40 D1 E9 13 C0 73 FA9 байт.


Це знову рівно, поки моє рішення, якщо ви (а) підкоряєтеся конвенції виклику cdecl і (b) фактично повертаєтесь з функції.
FUZxxl

@FUZxxl Якось я не бачив вашої версії. Ви абсолютно правильні. Я думав __fastcallі не мав цього ret.
Мірія

24

Збірка MMIX (28 байт)

64 бітові числа

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

Це збирається для:

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

Як це працює?

MORКоманда виконує матричне множення на два 64-бітових величин , використовуваних в якості два 8x8 матриць логічних значень. Булеве число з цифрами abcdefghklmnopqr 2 використовується як матриця на зразок цієї:

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

У MORмножать інструкції матриці представлені їх аргументами , де множення andі додавання or. Це є:

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

і далі:

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

що є зворотним порядком бітів вихідного числа.

32 бітові числа

Якщо ви просто хочете повернути 32-бітове число замість 64-бітного числа, ви можете використовувати цей модифікований метод:

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

зібрано:

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

Перше множення матриці в основному працює так:

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

відповідний октабайт, #0000000001020408який ми завантажуємо в перших двох інструкціях. Друге множення виглядає приблизно так:

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

Відповідний октабайт, #0102040810204080який ми створюємо з першої матриці так:

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

Друге множення є діловим, як зазвичай, отриманий код має однакову довжину (28 байт).


1
це перший раз, коли я чую про інструкцію щодо множення матриць на процесорі
phuclv

@ LưuVĩnhPhúc: Не матричне множення, але VAX мав інструкцію оцінювати поліном .
nneonneo

1
@nneonneo POLYІнструкція VAX - це в основному зрощене множення та додавання із вбудованим циклом. Подібні речі існують і в сучасних архітектурах (наприклад, x86), але вони, як правило, не мають вбудованого циклу, щоб оцінити одразу цілий поліном.
FUZxxl

12

80386 збірка ( 13 12 байт)

Як функція в синтаксисі AT&T, використовуючи конвенцію виклику 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

Ця функція збирається до наступної послідовності байтів:

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

Розбиті на інструкції:

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    

Це працює так: У кожній з 32 ітерацій циклу аргумент, який знаходиться на 4(%esp), прямо зміщений на одну позицію. Останній біт неявно переміщується у прапор перенесення. adcІнструкція додає два значення і додає значення прапора перенесення в результаті. Якщо ви додасте значення собі, тобто%eax фактично переміщуєте його на одну позицію. Це робить adc %eax,%eaxзручним способом зсув вліво %eaxна одну позицію, одночасно переміщуючи вміст прапора для перенесення в біт низького порядку.

Я повторюю цей процес 32 рази, щоб весь вміст завантажений 4(%esp)у %eax. Я ніколи прямо не ініціалізую, %eaxоскільки його попередній вміст зміщується під час циклу.


+1 Дякую за ваше останнє речення. Зараз очевидно, але я це пропустив.
edc65

1
Я завжди радий бачити тут рішення монтажу :)
user1354557

8

C,    63    52   48

Оригінальна версія:

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

Оновлена ​​версія (із змінами, запропонованими Allbeert , es1024 та Dennis ):

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

Примітка: Оскільки в другій версії не встановлено налаштування r=0, код передбачає, що а int- 32 біта. Якщо це припущення помилкове, функція, швидше за все, дасть неправильний результат, залежно від початкового стануr вході в функцію.


Остаточна версія (з подальшими змінами, запропонованими Деннісом та Алхіміком ):

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

Примітка. Це ставить декларацію робочих змінних rі iв список параметрів. Параметри такі: nце число, яке слід перевернути. rі iє змінними роботи, які повинні бути передані як 0.


1
Ви можете видалити intтип функції, а також змінити return rщось на зразок, i=rоскільки більшість компіляторів С зазвичай залишають результат останньої операції у регістрі повернення. Він працював на gcc та cl для мене.
Allbeert

1
Ви можете поголити ще 4 байти, скориставшись r(n){...}замістьr(int n){...}
es1024

2
@FUZxxl ви не можете опускати intв , int r=0,i=32;якщо ви не перемістите їх з тіла функції.
es1024

1
@FUZxxl: Не слід коментувати, коли я втомився ... Арифметичний зсув та поділ не рівноцінні; останній закруглюється до нуля, тоді як перший - до негативної нескінченності. -1 >> 1є -1для AS і 2**31 - 1для LS, а -1 / 2є 0.
Денніс

1
@Todd: Будь-яка причина, яку ви не визначили rі iяк аргументи? Врятували б ще три байти ...
Денніс

5

Джулія 0,2, 33 байти

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

Робить те, як це виглядає.

bits дає бітове представлення (зважаючи на доповнення двох). parseintне дбає про доповнення двох, але повертає 32-бітове ціле число, тож додаток двох обробляється переповненням.

Відповідно до журналів змін, parseintу Julia 0.3 було додано виявлення переповнення , тож це більше не може працювати.


5
Це виробничий код, а не код для гольфу! xD Я думаю, Юлія просто чудова.
cjfaure

4

Пітон 2, 50

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

Загалом те саме, що і моє рішення Pyth. Візьміть вхідний модуль 2 ** 32, перетворіть у 32-розрядний бінарний набій, оберніть назад, перетворіть бінарне жало в десяткове та друкуйте.


4

CJam, 15 байт

li4H#+2bW%32<2b

Спробуйте в Інтернеті.

Використовується жокер "Безкоштовна гра": Вихід завжди буде без підписаного цілого числа.

Тестові кейси

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

Як це працює

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

Функція, введення числа та повернення зворотного числа. Найбільш базовий алгоритм, напевно, можна пограти більше за допомогою розумного трюку.

Відредагуйте рекурсію замість циклу

Змініть 2 За пропозицією @bebe k*2замістьk<<1

Редагувати 3 Щось я взагалі пропустив: це 32-бітний цикл, не потрібно ініціалізувати k. Дякую @FUZxxl

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

Це було

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

Тест на консолі FireFox, протестуйте за допомогою чисел в ОП та ще декількох випадкових 16 і 32 бітових чисел

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

Приклад випробувального виводу

        -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для одноразового використання та R=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):kбагаторазового використання
bebe

@bebe :( Я переглядав свою відповідь за допомогою рекурсії і втратив усіх, щоб прочитати ваш коментар ...
edc65

2
ти на 38 байт, якщо k<<1стає k*2і v>>1стає v/2. він працював 486. Я не знаю про інші тестові справи
Bebe

1
@bebe v / 2 не працює для негативних чисел. 486/512 == 0,9 ... і 486 >> 9 == 0, обрізати це те саме. Але -90/128 == -0,7 ... і -90 >> 7 == - 1
edc65

4

x86, 10 байт

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

Це передбачає введення в eax, вихід в edx. (Крім того, на виході eax дорівнює нулю і встановлюються CF і ZF, якщо хтось дбає).

Замість лічильника на початку вводиться додатковий 1 як маркер кінцевих даних


Це насправді такий же розмір, як і моє рішення, який на три байти більше. Якщо ви додасте retінструкцію повернутися з функції та реалізуєте cdecl (тобто зміну rcr %eaxна rcr 4(%esp)та rcl %edxна rcl %eax), ви отримаєте один додатковий байт для retта ще два байти для посилання на пам'ять. Все-таки приємне рішення.
FUZxxl

3

J ( 17 15 13 байт)

_32#.@|.@{.#:

Ось чітке визначення для пояснення того, що він робить:

3 : '#. |. _32 {. #: y'
  1. #: yявляє yсобою базове 2 число, використовуючи стільки місць, скільки потрібно.
  2. x {. y займає |x (за величиною x) предмети зі yспереду, якщо xпозитивно, зі спини, якщо xнегативно. Якщо ми візьмемо більше предметів, ніж нині, результат отриманий нулями. _32 {. #: yефективно прокладки #: yдо 32 біт.
  3. |. yгортає y, я. повертає порядок елементів уy .
  4. #. y інтерпретує y як базу-2 число.


2

Пітон - 89

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

Python представляє негативні двійкові числа просто -0b{positive_number} . Отже, щоб розібратися з цим, доповніть від’ємні числа, а потім XOR усіма 1.

Після цього створіть рядкове представлення цілого числа на основі формату {:032b} який забезпечує 32-бітове представлення числа. Нарешті, оберніть рядок і поверніть його в ціле число.

EDIT

Дякуємо @Martin Büttner за те, що він вказав на проблему доповнення двох. Якщоn закінчується на 1, то доповненням двох буде зворотна версія.

На щастя, як пояснено вище, Python любить негативні двійкові числа досить простий спосіб. На щастя, intфункція Python дозволяє додаткові символи знаків у першому аргументі.

Тож тепер додайте знак мінус, якщо nце не задовольняє доповнення двох.


@ MartinBüttner Дякую Я спочатку пропустив таку можливість. Новий код краще обробляє доповнення двох.
BeetDemGuise

2
Можна трохи більше пограти в гольф: ['','-'][n%2]є '-'*(n%2).
Джастін

2

Піта , 33 32 22

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

Пояснення:

                 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.

Гольфи:

33 -> 32: Переміщено додавання до перегляду назад, щоб зберегти кінцеву цитату.

32 -> 22: Використовується Q mod 2 ^ 32 замість складної техніки. Об’єднали обидва рядки в одну.

Тестові приклади:

$ 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

Чи працює це з результатом як великі 32 числа, що мають лівий біт у 1? У цьому випадку воно повинно вивести негативне ціле число.
edc65

@ edc65 Я виводжу 32-бітне ціле число без підпису.
isaacg

2

GNU dc, 27 байт

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

Вихід:

$ 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 байт

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

Вихід:

$ ./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 функція, 89 байт

Та сама ідея, що і /codegolf//a/36289/11259 - використання хакерів на Стенфордському біті . Не збирається вигравати гольф, але все-таки цікаво:

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

Вихід:

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

2

Функція Java, 64 символи.

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

Також слід працювати в С.


2

PHP, 46 байт

Інтернет-версії

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

або

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

Це substrзайве (-12 байт). Ви повинні згадати, як їх запустити.
Тит

1
@Titus Ви спробували зразок -984802906?
Йорг Гюльсерманн

1
Вашу другу версію можна вдосконалити, щоб вона відповідала першій:<?=bindec(strrev(sprintf("%064b",$argn<<32)));
Крістоф

@Christoph дуже приємне поліпшення Дякую
Йорг Гюльсерманн

1

JS 115

Ну, це зовсім не добре: D

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

Метод @Florian F в JS становить 53 байти:

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

1
Ці it may be a functionкошти правило вам не потрібно попередження або швидке
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;}

Бітові операції, які, швидше за все, можна зробити коротшими на всіх мовах програмування.

В основному, проведіть через усі потужності 2 до цілого максимуму + 1 (що перетворюється на потужність двох), і оскільки (2,147,483,647 + 1) = 0 я можу перейти на 0. Біт зміщення Вліво вправо, щоб перемістити біт в перший положення. Останній біт на місці 32 проходить 31 крок вправо, другий останній - 30 і т.д. Так що, використовуючи оператор AND з 1, я знаю, чи це 1 або 0. Якщо це 1, я додамо поточне значення i до результату, і поверніть його.

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

Дрібні речі, але ви можете ініціалізувати, iколи ви оголошуєте це, і зберігати байт, видаляючи i++з циклу for, і замість того, щоб порівнювати результат 1&...з 0, ви можете видалити оператор if взагалі і помножити iна результат, що дає r|=i*(1&(V>>(31-l++)));всередині циклу
VisualMelon

Розумний! У мене було відчуття, що я щось пропускаю. Спасибі!
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);}

Розширено

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

1

Пітон - 37

Схожий на рішення @ isaacg.

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

1

C ++, 160

Це не найкоротший, проте він використовує лише 24 операції.
Взято з книги захоплення Хакера.

Гольф:

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

Безголівки:

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
Це кодове питання про гольф. Спробуйте зменшити кількість символів у вашому рішенні, а не кількість операцій.
FUZxxl

1

Haskell, 145 - жодних побітних операцій

Біт-подвійність вражає мене як антитезу Haskell, тому я уникав будь-якого використання побітових операторів. Отримана програма, безумовно, не найкоротший конкурсант, але я вважав, що використання математики замість біт-твідінгу було принаймні цікавим.

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

Пояснення

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. використовує модуль для приведення результату в 32-бітний діапазон
  2. будує список 0 s і 1s, найменш значущий біт спочатку багаторазовим діленням на 2 і взяттям решти
  3. з'єднує нескінченний список 0s до кінця цього списку
  4. захоплює перші 32 елементи списку (Ці останні два потрібні були для того, щоб перелік справді був 32-бітний.)
  5. перетворює список 0і 1в ціле число передбачає найбільш значимий біт спочатку (повторюється двічі і додати).

Я не зовсім впевнений, що являє собою "стандартну бібліотеку" в Haskell, тому я припустив, що Data.Tuple і Data.List були в порядку (вони досить стандартні).

Крім того, вихід є 32-бітним цілим числом без підпису, оскільки зміни, які коштували б мені байтів: я аргументую це пунктом "упущення - безкоштовна гра".


Стандартна бібліотека: що відповідає мові. Сюди входять заголовки системи для C, 4000+ класів і методів у Java (більшість не стосуються).
Ісія Медоуз

1

PHP, 46 41 байт

спробуйте їх в Інтернеті

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

побіжно ... більш-менш. Запустити як труба php -nR '<code>'.

PHP, 46 байт

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

чистий розрядний розчин; запустити як труба з -nR.

PHP, 47 59 байт

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

інший вбудований підхід; зберегти у файл та запустити як pipe -F.


0

Perl - 60

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

+1 для прапора p (дайте мені знати, чи вважаю я це неправильно).

Виконати з:

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 що це e;i;? Декларації без типу не є дійсними C ++. Для змінних це не вірно навіть C.
Руслан

@Ruslan я не впізнав "++" у назві, вибачте. (Я не погодився б із вашим другим твердженням)
bebe

int r(int n){int e=0,i=0;for(;i<32;)e=e*2|1&n>>i++;return e;}61 байт :)
Крістоф

0

R, 45

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

Приклади:

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

Завжди просто соромлячись відповідей Python. Це прокляте функціональне слово.


0

Рубі, 43 41 байт

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

У Ruby, використовуючи позначення індексу дужок (foo [i]), повертає біт на n-е місце.

--Edit--

Рефакторинг injectфункціональності голить пару байтів

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}

Нічого фантазійного. Він зміщує вихідний ліворуч, скопіюйте lsb перед зміщенням джерела вправо.



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.