Великий або Маленький Ендіан


57

Напишіть програму або функцію, яка виводить Lif, який виконується на маленькій архітектурі ендіану, або Bif, якщо він працює на великій архітектурі ендіан. Вихід з нижнього регістру lабо bтакож прийнятний.

Введення немає.

Підрахунок балів - це гольф з кодом, тому виграє код з найменшими байтами.

Редагувати: Відповідно до коментарів, наведених нижче, я уточнюю, що запис повинен бути спроможний працювати на будь-якій архітектурі.

Я вважаю, що на це впливає лише одна відповідь, і ця відповідь чітко вказує, що це так.


1
Пам'ять коробки. Я не впевнений, що ви маєте на увазі
Ліам

7
Я думаю, що це цікавий виклик (і це вихід поза норму), але перевірити це буде дуже важко. Тим більше, що більша частина коду виявиться надзвичайно платформою.
DJMcMayhem

7
Так, я думаю, що це буде цікаво, тому що, сподіваємось, це щось, з чим езоланги та гольф мови мають складніше, ніж "звичайні" мови. У мене є відчуття, що їх не буде так важко перевірити. Найгірший випадок, коли вони мають бути перевірені вручну
Ліам

2
Я думаю, що відповідь на основі конкретного машинного коду заборонена? В іншому випадку B0 4C C3, що є mov al, 'L' / retабо unsigned char f(){ return 'L'; }, було б коректною відповіддю x86.
Маргарет Блум

5
Браво! для виклику гольфу з кодом, в якому мови програмування загального призначення можуть бути конкурентоспроможними.
PellMell

Відповіді:


42

Пітон, 33 байти

import sys
exit(sys.byteorder[0])

sys.byteorderє 'little'або 'big'(або для тих із вас, хто прочитає це речення, не дивлячись на код, [0]означає взяти перший символ).


У виклику сказано, що вихід повинен бути Lі B(або малим варіантом), а не всім словом.
user2428118

43
Ось чому це говорить sys.byteorder[0], тобто перша ознака byteorder.
s3lph

36

C, 26 байт

a=66<<24|76;f(){puts(&a);}

Припускає 32-бітні intта ASCII символи. Випробовується на amd64 (мало-ендіанський) та mips (big-endian).

GCC, 23 байти

00000000: 613d 2742 0000 4c27 3b66 2829 7b70 7574  a='B..L';f(){put
00000010: 7328 2661 293b 7d                        s(&a);}

Запропоновано feersum. Значення багатосимвольних констант залежить від реалізації, але це, здається, працює в GCC. Випробували на тих же архітектурах.


7
Коротше a='B\0\0L';В \0s можуть бути замінені нульовими байтами.
feersum

1
@feersum Схоже, що залежність від констант багато символів залежить від реалізації. Я б зазвичай не хвилювався з приводу цього в гольф-коді, але ця проблема полягає в тому, щоб розрізняти реалізацію.
Anders Kaseorg

Чи працює цей код зараз у чомусь іншому, ніж GCC?
feersum

1
@feersum C89 дозволяє обидва.
Anders Kaseorg

1
Використовуючи xlc (VisualAge C ++ Professional / C для AIX Compiler, версія 6) на RS6000 під керуванням AIX 5.2, програма 26-байт успішно друкує "B"
Джеррі Єремія

24

MATLAB / Октава, 24 байти

[~,~,e]=computer;disp(e)

computerФункція дає інформацію про, ну, комп'ютер він працює на. Третій результат - це ендіанство: Lабо Bдля мало-, або для великого ендіана відповідно.

Спробуйте це на Ideone .


1
що. Це дещо для stackoverflow, я цього не знав!
Brain Guider

20

JavaScript ES6, 50 байт

_=>"BL"[new Int8Array(Int16Array.of(1).buffer)[0]]

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


5
Люди WebGL вважали, що це гарна ідея, щоб уникнути необхідності конвертувати витривалість при переході до GPU. Досить багато інших вважали це дурним… :(
gsnedders

11

C, 36 35 байт

1 байт завдяки @algmyr та @owacoder.

main(a){printf(*(char*)&a?"L":"B");}
main(a){putchar(66+10**(char*)&a);}
main(a){putchar("BL"[*(char*)&a]);}

Кредити тут .

Не перевірений, оскільки у мене немає машини з великим ендіанством.


2
Чи допускає специфікація C функцію з одним аргументом main?
CodesInChaos

@codesinchaos так, це так. Це буде кількість наведених аргументів командного рядка. Зазвичай тут використовується ініційована змінна, 1оскільки не вводиться вхід (а назва програми завжди вважається першим аргументом)
Ліам

2
@Liam: Якщо дозволено щось, крім 0 або 2, реалізація визначена в C11.

1
Або main(a){putchar("BL"[*(char*)&a]);}.
owacoder

2
Якщо ви заплуталися з конвенцією виклику він йде вниз до 31: main(char a){putchar("BL"[a]);}.
Андреа Біондо

8

Математика, 22

{B,L}[[$ByteOrdering]]

Це, ймовірно, порушує якесь правило про невикористання вбудованої функції, але я не дуже зацікавлений в альтернативі золотій обробці.


1
Вбудовані файли чудово (більшість відповідей також використовує їх)
Ліам

2
І ще раз, у Mathematica є вбудований!
gcampbell

3
Я думаю, що це фрагмент, а не програма чи функція, і вам слід додати, &щоб зробити його функцією. (Але може виникнути розбіжність з приводу того, що являє собою "програма".)
Anders Kaseorg

1
@Anders Я не дуже знайомий з сучасними стандартами PCG (якщо я коли-небудь був), але IMHO однією перевагою інтерпретованої мови є те, що фрагмент - це програма. Це може бути запущено окремо, як і будь-яка інша програма в Mathematica .
Mr.Wizard

1
@ Mr.Wizard Зауважте, що "програма" в Mathematica посилається на окремий сценарій (який вимагає явного друку), тоді як у цій відповіді використовується відповідь REPL.
LegionMammal978

8

С, 27

На один байт довше, але ось все одно:

f(){putchar(htons(19522));}

Це добре працювало, чи можете ви мені поясніть, будь ласка.
ABcDexter

3
@ABcDexter бінарне розширення 19522 р. Є 1001100 01000010(простір для розділення байтів). Тепер, якщо взяти кожен байт, перетворити його назад на базу 10 і перевірити таблицю ASCII, ви побачите, що ця послідовність байтів еквівалентна LB. htonsбуде робити свою справу , і putcharбуде друкувати тільки LSB. У великих-ендіанських системах, які будуть B, у мало-ендіанських, htonsбудуть перевернуті байти, тому LSB є L.
Кролтан

Замінити 19522з 'LB'попередженнями компілятора і -1 байт.
Стен Струм

8

Код машини PowerPC - 20 байт

PowerPC є бієндіанським (витривалість можна встановити при запуску), тому цей код повинен відповідати запиту на виклик можливості роботи як на BE, так і на LE машинах. Це функція, яка повертає 1 'L' або 'B'залежно від встановленої в даний час витримки.

Як функція, AFAICT відповідає SVR4 PowerPC ABI (використовується Linux на ppc32), PowerOpen ABI (використовується, наприклад, AIX) та OS X ABI. Зокрема, він покладається лише на те, що GPR 0 - це регістр непостійних подряпин, а GPR 3 використовується для повернення "малих" значень.

00000000 <get_endian>:
   0:   7c 00 00 a6     mfmsr   r0
   4:   54 03 0f fe     rlwinm  r3,r0,1,31,31
   8:   1c 63 00 0a     mulli   r3,r3,10
   c:   38 63 00 42     addi    r3,r3,66
  10:   4e 80 00 20     blr

Тепер це виходить так:

  • MSR зчитується в GP регістра 0; MSR містить в біті 31 параметри ендіанності (0 = великий ендіан; 1 = маленький ендіан);
  • rlwinmвитягує саме цей біт: він приймає значення в GPR0, r відміняє l eft на 1 місце (так що тепер знаходиться в положенні 0) і m запитує його з 1 (маска, згенерована тими 31,31 2 ); результат заноситься до реєстру лікарів 3;
  • помножити результат на 10 і суму 66 ( 'B') (10 - різниця між 'L'і 'B')
  • нарешті, поверніться до абонента

Примітки

  1. так, питання задає друк , але не ясно, як я повинен надрукувати речі в зборах, які, як очікується, працюватимуть без змін у різних операційних системах. =)
  2. для зацікавлених див. документацію на rlwinm ; знаючи майже нічого про PowerPC, я знайшов подібні інструкції надзвичайно цікавими.

    Оновлення 2018 року : Реймонд Чен публікує серію про архітектуру PowerPC, ви можете знайти тут його чудовий пост про rlwinm& друзів.


7

Java 8, 96, 64 52 байти

()->(""+java.nio.ByteOrder.nativeOrder()).charAt(0);

Гольф, заснований на цій відповіді ТАК . Весь кредит припадає на @LeakyNun та @AlanTuning. Java зберігає програшну смугу.

96 байт:

 char e(){return java.nio.ByteOrder.nativeOrder().equals(java.nio.ByteOrder.BIG_ENDIAN)?'b':'l';}

64 байти:

char e(){return(""+java.nio.ByteOrder.nativeOrder()).charAt(0);}

Неперевірений b / c Я не маю доступу до машини великого ендіану.


1
char e(){return(""+java.nio.ByteOrder.nativeOrder()).charAt(0);}
Лина монашка

char e(){return(""+java.nio.Bits.byteOrder()).charAt(0);}
Leaky Nun

@LeakyNun Я не бачу бітів в Java API, і коли я запускаю, це дає мені "Біти не є загальнодоступними в java.nio"
Синій

О, добре тоді.
Leaky Nun

52 байти, якщо ви використовуєте лямбда! ()->(""+java.nio.ByteOrder.nativeOrder()).charAt(0);
Shaun Wild

6

Perl, 38 36 байт

say+(pack"L",1 eq pack"V",1)?"L":"B"

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


6

(G) Далі, 24 байти

here $4200004C , c@ emit

Передбачається, що комірки мають 32 біти (і що ваш інтерпретатор Forth підтримує базові префікси Gforth ). Він просто зберігає число 0x4200004C в пам'яті, а потім відображає байт в нижньому кінці.


5

C, 34 байти

Це передбачає кодування ASCII символів

main(a){putchar(66+10**(char*)a);}

Телефонуйте без аргументів.

Пояснення:

По дзвінку aбуде 1. *(char*)aотримує доступ до першого байтуa , який на платформах малого ендіану становитиме 1, на платформах big-endian буде 0.

Тому на великих платформах ендіану цей код передаватиме 66 + 10 * 0 = 66 до putchar. 66 - код ASCII для B. На платформах з малим ендіаном він передасть 66 + 10 * 1 = 76, що є кодом ASCII L.


5

C #, 60 52 байти

C # напрочуд конкурентоспроможний у цьому.

char e=>System.BitConverter.IsLittleEndian?'L':'B';

Зарахування Groo за синтаксис C # 6.

60 байт:

char e(){return System.BitConverter.IsLittleEndian?'L':'B';}

За допомогою синтаксису C # 6 ви можете трохи скоротити його: char e=>System.BitConverter.IsLittleEndian?'L':'B';звичайно, це (як і відповідь Java) насправді не друкує значення.
Groo

Ласкаво просимо до головоломки програмування та коду для гольфу! Це хороша перша відповідь.
Алекс А.

5

Юлія, 24 19 байт

()->ntoh(5)>>55+'B'

Це анонімна функція, яка не приймає даних і повертає a Char . Щоб викликати його, призначте його змінній. Передбачається, що цілі числа є 64-бітними.

ntohФункція перетворює байтів в значення , передане в нього з мережевого порядку байт (великий байтів) до свого хост - комп'ютером. На великих ендіанських машинах ntoh- це функція ідентичності, оскільки не потрібно здійснювати перетворення. На маленьких ендіанських машинах байти міняються місцями, так ntoh(5) == 360287970189639680. Що також, можливо, читабельніше, дорівнює: 0000010100000000000000000000000000000000000000000000000000000000у двійковій формі .

Якщо ми точно зрушимо результат ntoh(5)на 55, ми отримаємо 0 на великих ендіанських машинах і 10 на маленьких ендіанських машинах. Додавши це до константи символів 'B', ми отримаємо 'B'або 'L'для великих, або маленьких ендіанських машин відповідно.

Збережено 5 байт завдяки FryAmTheEggman та Dennis!


Для 32-х бітових вам доведеться змінити 55 на 23 (також 5 в 16-бітовому повинен був бути 7, моя помилка). Я думаю, що Денніс мав на увазі щось на кшталт ()->ntoh(5)>>55+'B':?
FryAmTheEggman

1
f()='L'-ntoh(10)%16і f()='L'-ntoh(10)&10повинен працювати на всіх платформах.
Денніс


5

Лист звичайний, 27 байт

Тестували на SBCL та ECL. Для портативного підходу слід використовувати тривіальні функції .

(lambda()'L #+big-endian'B)

#+Позначення є умовою для читання часу , який зчитує наступну форму , тільки якщо умовний вираз істинно. Тут умовою є весь #+big-endianтекст, що означає, що тест буде виконаний, якщо :big-endianключове слово належить до *FEATURES*списку (список, який містить, крім іншого, інформацію, що стосується платформи). Наступний вираз - 'Bце читання чи пропуск відповідно до результату тесту. Якщо ваша платформа є big-endian і ви пишете вищезазначену форму в REPL, то це так, як якщо б ви написали наступне:

CL-USER>(lambda()'L 'B)

(NB. CL-USER>Підказка)

Тіло функції є неявним PROGN, тобто повертається лише оцінка останнього виразу. Таким чином, вище на насправді повертає символ B. Якщо ж умова часу читання оцінюється як хибна, форма записується так, ніби ви написали:

CL-USER>(lambda()'L)

... який просто повертає символ L.


Знімки заборонені; пишіть натомість повні програми або функції.
Ерік Аутгольфер

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Оновлено, дякую
coredump

Примітка. Фрагменти дозволені лише в тому випадку, якщо це чітко дозволено ОП.
Ерік Аутгольфер

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Чи можете ви надати посилання на це? Тут є інші відповіді REPL та / або фрагменти оболонки, і цей мета-пост може запропонувати, що відповіді на відповідь REPL за замовчуванням можуть бути нормальними. Дякую.
coredump

5

ARMv6 та новіших версій: машинний код 20 байт

0xE10F1000 : MRS   r0,CPSR        ; read current status register
0xE3110C02 : TST   r0,#1<<9       ; set Z flag if bit 9 set
0x03A0004C : MOVEQ r0,#'L'        ; return 'L' if Z clear
0x13A00042 : MOVNE r0,#'B'        ; return 'B' if Z set
0xEBxxxxxx : BL    putchar        ; print it (relative branch)

Неперевірений, оскільки у мене немає підходящої машини. Біт 9 CPSR надає поточну небезпеку завантаження / зберігання.


Ви можете використовувати повернення з функції ( BX lrтак?) Замість putchar, тому що r0це правильний регістр для повернутого результату.
anatolyg

Дійсно, це (насправді MOV pc, lr) було в одному з моїх попередніх редагувань. Однак це відповідає специфікації для друку листа, а не просто його повернення.
користувач1908704

Можливо, я читаю посилання неправильно, але я думаю, що це можна зробити в кодуванні інструкції "великий палець 2". Це означало б, що першою інструкцією залишилось 32 біта ("кодування T1" на сторінці F7-2720 довідкового посібника ARM v8, що зробило б це 0xF3EF_8000); другий - також 32 біти (кодування операнда є трохи химерним, але його можна зробити за допомогою "i: imm3", встановленого на 0010, і "imm8" на 00000010, що дає загальну інструкцію 0xF010_2F02). Перед третьою інструкцією нам потрібно вставити "ITE EQ" (0xBF0C), щоб контролювати умови в наступних двох інструкціях MOV, які стають 0x204C і ...
Jules

... 0x2042 (збереження всього 2 байт). Тоді остаточну інструкцію BL представляти трохи складно, тому що біти адреси, яку ми не знаємо, в кінцевому підсумку розкидані між бітами інструкції, які ми знаємо, але це також 32-бітове кодування, тому результат буде становитиме 18 байт (F3 EF 80 00 F0 10 2F 02 BF 0C 20 4C 20 42 F? ?? ?? ??). Я вважаю, що це змінює архітектуру на ARMv8 і пізніші версії, хоча це може працювати в ARMv7 (?).
Жуль

4

Perl 5, 21 + 1 = 22 байти

Бігайте з perl -E.

say ord pack(S,1)?L:B

Випробовується на amd64 (мало-ендіанський) та mips (big-endian).


Чи -Eпрапор дійсно необхідний у підрахунку байтів? Можна просто сказати, що ви використовуєте Perl 5.10 (оскільки sayкоманда доступна в цій версії)
Пол Пікард

1
@PaulPicard Але use 5.10.0;ще багато байтів!
Anders Kaseorg

1
@PaulPicard Ваша думка неправильна. Perl 5.10 вимагає -Eперемикача або useзаяви для say.
Anders Kaseorg

3
-Eє "безкоштовним" на PPCG. Не потрібно нічого додавати.
Вен

1
(однак -nі -pне є)
Вересень

4

R, 28 23 байти

substr(.Platform$endian,1,1)

.Platform$endianповертається, bigякщо працювати на великому ендіані та littleякщо на малому. Тут, використовуючи substr, він повертає першу літеру виводу, так що bабоl .

Оскільки endianце єдиний об'єкт, що починається з об'єкта, який eміститься в об'єкті, .Platformми можемо зменшити його завдяки частковій відповідності наступним кодам 23 байтів:

substr(.Platform$e,1,1)

3

Clojure, 46 44 байти

#(nth(str(java.nio.ByteOrder/nativeOrder))0)

Це функція, яка використовує вбудований Java, щоб отримати витривалість машини. Потім знайдіть його рядкове представлення, яке буде або "LITTLE_ENDIAN"або, "BIG_ENDIAN"і візьміть перший символ того, який би рядок був обраний, і поверніть його.

Збережено 2 байти завдяки @ cliffroot .


Що таке насправді кложур, це лісп або джава?
Leaky Nun

@LeakyNun Можливо, практичний LISP, який працює з Java? Важко сказати.
миль

#(nth(str(java.nio.ByteOrder/nativeOrder))0)на 2 байти коротше
скеля

3

Рубі, 3130 символів.

puts [1].pack("s")>"\01"??L:?B

Хм, повинен бути кращий спосіб. Налічіть 5 символів менше, якщо знака не потрібно виводити, як я думаю, інші рішення опускають друк. тобто видаліть частину "ставить", якщо ви нічого не хочете надрукувати.


Якщо я добре пам’ятаю, після Ruby 1.9 ви можете використовувати ?Lі ?Bзамість puts :Lіputs "B"
Sherlock9

Думаю puts [76,66].pack("s")[0], спрацює.
Уейн Конрад

@ Sherlock9, дякую, на один чар менше. @WayneConrad, Можливо, додамо свою відповідь, я не маю під рукою великої ендіанської машини для тестування, але на маленькому ендіані це працює. Але зміна , як це не працює: puts [76,66].pack("s>")[0]. Це означає, що можна не працювати над великим ендіаном з якихось причин, я не добре розумію. Але це, здається, працює (виходить із вашого рішення) puts [19522].pack("s>")[0]. WDYT? Цікаво, чи зможу я знайти десь оцінити на великому ендіані.
акостадінов

На жаль, мені також не вистачає великої ендіанської машини, щоб перевірити.
Уейн Конрад

3

Bash (та інші оболонки Unix), 32 (33) байти

Перша та друга спроба:

case `echo|od` in *5*)echo B;;*)echo L;;esac # portable
[[ `echo|od` =~ 5 ]]&&echo B||echo L         # non-portable

Завдяки Деннісу, коротша версія:

od<<<a|grep -q 5&&echo L||echo B  # non-portable
echo|od|grep -q 5&&echo B||echo L # portable

echoУтиліта виводить символ нового рядка, з шістнадцятковим значенням 0A, і ніякого іншого висновком. Бо <<<aвоно є 61 0A.

odУтиліта, за замовчуванням, інтерпретує введення як два байти слово, доповнені нулі , якщо кількість байт непарній, і перетворює в вісімкову системі . Це призводить до того, що вихід ехо буде інтерпред як 0A 00, який перетворюється на 005000велике-ендіанське або 000012мало-ендіанське. 61 0Aстає 005141в мало-ендіанський і 060412в великий-ендіанський. Повний вихід ода також включає в себе адресу і розмір даних означає , що ми не можемо використовувати 0, 1або 2для випробування.

Команда є чітко визначеною для викриття системи. Зі стандартного :

Порядок байтів, що використовується при інтерпретації числових значень, визначається реалізацією, але повинен відповідати порядку, в якому константа відповідного типу зберігається в пам'яті в системі.

Нотатки про сумісність

Я не впевнений, якщо введення echo|odзворотних цитат без подвійних лапок навколо них [що призводить до трисловного аргументу case] підтримується у всіх системах. Я не впевнений, чи всі системи підтримують сценарії оболонки без закінчення нового рядка. Я здебільшого впевнений, але не на 100% від поведінки од додавання байта для прокладки у великих ендіанських системах. При необхідності echo aможна використовувати для портативних версій. Усі сценарії працюють у bash, ksh та zsh, а портативні - у dash.


Жодна із змін не потрібна; просто поставте одну шкаралупу, в якій вона працює, у мовний гарнітур, і ви налаштовані.
Денніс

1
@Dennis Мені подобається робити що - то аналізу ... хоча це цікавіше , якщо я дійсно знайти що - щось нестандартне , який отримує більше коротку відповідь на баш або Zsh , ніж інші. Можливо, я побачу, що можна зробити[[
Random832

1
Нічого поганого в аналізі. Останній абзац просто пролунав так, ніби ви були невпевнені в тому, що відповідь, що стосується оболонки, є дійсною ... od<<<a|grep -q 5&&echo L||echo Bповинна працювати в Bash та інших.
Денніс

Я перевірив його на VM з великим ендіаном і echo|odдрукує так, 0000000\n005000\n0000001як ви очікували.
Денніс

@ user17752 Оскільки витривалість не впливає на вихід od -a.
Випадково832

3

PHP, 16 байт

<?=pack(S,14)^B;

Для цього використовуються два хитрощі, які не використовуються в двох існуючих відповідях PHP:

  1. Значення, передане для pack () або unpack (), може бути будь-яким, а не лише 0 або 1.
  2. Бітовий оператор XOR ( ^) працює на рядках, і результат лише до тих пір, як коротший рядок, уникаючи потреби в індексації рядків або потрійному операторі.

2

Вузол, 42 байти

n=>require('os').endianness()[0]

Про: є вбудований. Кон: Назви властивостей дуже довгі


2

PowerShell, 44 байти

[char](66+10*[BitConverter]::IsLittleEndian)

Характер 66 Bі 10 символів пізніше це число 76, L. Булеве значення "true" стає 1при передачі на число. BitConverterстандартний клас .NET.


1

Ракетка, 35 28 байт

(if(system-big-endian?)'B'L)

'Bабо 'Lвідповідно Повідомте мене, якщо це недостатньо конкретно :)



1

Haskell (використовуючи числові типи з обмеженим розміром лише для GHC), 75 байт

import Unsafe.Coerce
import GHC.Int
f="BL"!!fromEnum(unsafeCoerce 1::Int8)

(не перевірено на архітектурі великого ендіану, але здається, що це повинно працювати!)


1

К, 15 байт

    ("bl")@*6h$-8!`
    ,"l"

Пояснення;

    From right to left;
    -8!`       /serialises the back tick and returns (0x010000000a000000f500)
    6h$-8!`    /This casts the result to `int which is type 6h(could have used `int$-8!`) - the result is (1 0 0 0 10 0 0 0 245 0i)
    *6h$-8!`   /* means first, we take the first item which is 1. Since it will be either 1 or 0, we can use it to index (@) into the two element list on the left i.e. ("bl")1 returns "l" and ("bl")0 returns b

1

Баш, 27 байт

iconv -tucs2<<<䉌|head -c1

( U + 424C ) кодується в вигляді трьох UTF-8 байт: E4 89 8C.

Передбачається, що iconvвикористовується функція від glibc і що використовується локаль UTF-8.

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