# Big or Little Endian

Write a program or function that outputs an L if run on a little endian architecture or a B if run on a big endian architecture. Lower case output l or b is also acceptable.

There is no input.

Scoring is code golf, so the code with the fewest bytes wins.

Edit: As per the comments below, I am clarifying that the entry must be able to run on either architecture.

I believe that there is only one answer that this affects, and that answer has clearly indicated that this is the case.

• The memory of the box. I'm not sure what you mean – Liam Jul 27 '16 at 23:38
• I think this is an interesting challenge (and it's way out of the norm) but it's going to be extremely hard to test it. Especially since most of the code will end up being extremely platform specific. – DJMcMayhem Jul 27 '16 at 23:41
• Yeah I think it'll be interesting because hopefully it's something that esolangs and golfing languages have a harder time with than 'normal' languages. I have a feeling that they won't be that hard to verify. Worst case they should be verifiable by hand – Liam Jul 27 '16 at 23:43
• I guess an answer based on a specific machine code is forbidden? Otherwise B0 4C C3, which is mov al, 'L' / ret or unsigned char f(){ return 'L'; }, would be a valid x86 answer. – Margaret Bloom Jul 28 '16 at 7:28
• Bravo! for a code golf challenge in which general-purpose programming languages can be competitive. – PellMell Jul 29 '16 at 21:16

# Python, 33 bytes

import sys
exit(sys.byteorder[0])


sys.byteorder is either 'little' or 'big' (and for those of you who will read this sentence without looking at the code, [0] means take the first character).

• The challenge says the output must be L and B (or the lowercase variant), not the entire word. – user2428118 Jul 28 '16 at 12:01
• That's why it says sys.byteorder[0], i.e. the first char of byteorder. – s3lph Jul 28 '16 at 12:03

# C, 26 bytes

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


Assumes 32-bit int and ASCII characters. Tested on amd64 (little-endian) and mips (big-endian).

# GCC, 23 bytes

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


Suggested by feersum. The value of multi-character constants is implementation-dependent, but this seems to work in GCC. Tested on the same architectures.

• Shorter is a='B\0\0L'; The \0s can be replaced with null bytes. – feersum Jul 28 '16 at 3:49
• @feersum The endianness of multi-character constants seems to be implementation dependent. I wouldn't normally worry about that much in code golf, but this challenge is all about distinguishing between implementations. – Anders Kaseorg Jul 28 '16 at 5:11
• Does this code currently work in something other than GCC? – feersum Jul 28 '16 at 5:27
• @feersum C89 allows both. – Anders Kaseorg Jul 28 '16 at 5:49
• Using xlc (VisualAge C++ Professional / C for AIX Compiler, Version 6) on an RS6000 running AIX 5.2 the 26 byte program successfully prints "B" – Jerry Jeremiah Jul 28 '16 at 5:59

# MATLAB / Octave, 24 bytes

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


The computer function gives information about, well, the computer it's running on. The third output is endianness: L or B for little- or big-endian respectively.

• what. This is somethign for stackoverflow, I didnt know this! – Brain Guider Jul 28 '16 at 13:09

# JavaScript ES6, 50 bytes

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


I don’t know who decided it was a good idea for TypedArray objects to expose the native endianness of the interpreter, but here we are.

• WebGL people thought it was a good idea, to avoid having to convert endianness when passing to the GPU. Pretty much everyone else thought it stupid… :( – gsnedders Jul 29 '16 at 13:49

# C, 36 35 bytes

1 byte thanks to @algmyr and @owacoder.

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


Credits here.

Untested since I don't have a big-endian machine.

• Does the C spec allow a one-argument main function? – CodesInChaos Jul 28 '16 at 10:00
• @codesinchaos yes it does. It will be the number of command line arguments given. Usually here it is used to have a variable initiated to 1 because no input is given (and the program name always counts as the first argument) – Liam Jul 28 '16 at 10:47
• @Liam: If anything other than 0 or 2 is allowed is implementation defined in C11. – user16488 Jul 28 '16 at 12:47
• Or main(a){putchar("BL"[*(char*)&a]);}. – owacoder Jul 28 '16 at 20:59
• If you mess with the call convention it goes down to 31: main(char a){putchar("BL"[a]);}. – Andrea Biondo Jul 29 '16 at 14:29

{B,L}[[$ByteOrdering]]  This probably breaks some rule about not using a built-in function but I'm not really interested in rube goldberging an alternative. • Built-ins are fine (most answers are using them too) – Liam Jul 28 '16 at 10:49 • And once again, Mathematica has a built-in! – gcampbell Jul 28 '16 at 12:06 • I think this is a snippet, not a program or function, and you should add & to make it a function. (But there may be disagreement over what constitutes a “program”.) – Anders Kaseorg Jul 28 '16 at 20:24 • @Anders I am not really familiar with the current standards for PCG (if I ever was) but IMHO one advantage of an interpreted language is that a snippet is a program. This can be run in a stand-alone manner as much as any other program in Mathematica. – Mr.Wizard Jul 29 '16 at 5:40 • @Mr.Wizard Note that a "program" in Mathematica refers to a standalone script (which requires explicit printing), whereas this answer uses the REPL. – LegionMammal978 Jul 30 '16 at 22:50 # C, 27 One byte longer, but here it is anyway: f(){putchar(htons(19522));}  • It worked fine, can you please explain it to me. – ABcDexter Jul 30 '16 at 8:29 • @ABcDexter the binary expansion of 19522 is 1001100 01000010 (space to separate bytes). Now if you take each byte, convert back to base 10 and check the ASCII table, you will see that this byte sequence is equivalent to LB. htons will do its thing, and putchar will only print the LSB. In big-endian systems, that will be B, in little-endian, htons will have flipped the bytes, so the LSB is L. – Kroltan Jul 31 '16 at 15:42 • Replace 19522 with 'LB' for compiler warnings and -1 byte. – Stan Strum Feb 7 '18 at 20:58 # PowerPC machine code - 20 bytes PowerPC is bi-endian (the endianness can be set up at startup), so this code should conform to the challenge request of being able to run both on BE and LE machines. This is a function that returns1 'L' or 'B' depending on the endianness currently set. As a function, AFAICT it conforms the SVR4 PowerPC ABI (used by Linux on ppc32), the PowerOpen ABI (used e.g. by AIX) and the OS X ABI. In particular, it relies just on the fact that GPR 0 is a volatile scratch register, and GPR 3 is used to return "small" values. 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  Now, it goes like this: • the MSR is read into GP register 0; the MSR contains at bit 31 the endianness settings (0 = big endian; 1 = little endian); • rlwinm extracts just that bit: it takes the value in GPR0, rotates left by 1 place (so that now is in position 0) and masks it with 1 (the mask generated by those 31,312); the result is put into GP register 3; • multiply the result by 10 and sum 66 ('B') (10 is the difference between 'L' and 'B') • finally, return to the caller ### Notes 1. yep, the question does ask to print, but it's not clear how I should print stuff in assembly expected to run unmodified on different operating systems. =) 2. for those interested, see the rlwinm documentation; knowing next to nothing about PowerPC, I found this kind of instructions extremely interesting. 2018 update: Raymond Chen is publishing a series about the PowerPC architecture, you can find here his great post about rlwinm & friends. # Java 8, 96, 64 52 bytes ()->(""+java.nio.ByteOrder.nativeOrder()).charAt(0);  A golf based on this SO answer. All credit goes to @LeakyNun and @AlanTuning. Java keeps the loosing streak. 96 bytes:  char e(){return java.nio.ByteOrder.nativeOrder().equals(java.nio.ByteOrder.BIG_ENDIAN)?'b':'l';}  64 bytes: char e(){return(""+java.nio.ByteOrder.nativeOrder()).charAt(0);}  Untested b/c I don't have access to a big-endian machine. • char e(){return(""+java.nio.ByteOrder.nativeOrder()).charAt(0);} – Leaky Nun Jul 28 '16 at 1:15 • char e(){return(""+java.nio.Bits.byteOrder()).charAt(0);} – Leaky Nun Jul 28 '16 at 1:22 • @LeakyNun I don't see Bits in the Java API, and when I run it it gives me "Bits is not public in java.nio" – Blue Jul 28 '16 at 2:07 • Oh, alright then. – Leaky Nun Jul 28 '16 at 2:14 • 52 bytes if you use a lambda! ()->(""+java.nio.ByteOrder.nativeOrder()).charAt(0); – Shaun Wild Jul 28 '16 at 10:41 # Perl, 38 36 bytes say+(pack"L",1 eq pack"V",1)?"L":"B"  Works by packing a number in the system's default byte order and comparing it to a number packed in little-endian byte order. # (G)Forth, 24 bytes here$4200004C , c@ emit


Assumes that cells are 32 bits (and that your Forth interpreter supports Gforth's base prefixes). It simply stores the number 0x4200004C in memory and then displays the byte at the low end.

# C, 34 bytes

This assumes ASCII character encoding

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


Call without argument.

Explanation:

On call, a will be 1. *(char*)a accesses the first byte of a, which on little-endian platforms will be 1, on big-endian platforms will be 0.

On big-endian platforms, this code will therefore pass 66 + 10*0 = 66 to putchar. 66 is the ASCII code for B. On little-endian platforms, it will pass 66 + 10*1 = 76, which is the ASCII code for L.

# C#, 60 52 bytes

C# is surprisingly competitive in this one.

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


Credits to Groo for the C#6 syntax.

60 bytes:

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

• With C#6 syntax you can shorten it a bit: char e=>System.BitConverter.IsLittleEndian?'L':'B';, of course this (as well as the Java answer) doesn't actually print the value. – Groo Jul 28 '16 at 10:09
• Welcome to Programming Puzzles & Code Golf! This is a nice first answer. – Alex A. Jul 29 '16 at 4:48

# Julia, 24 19 bytes

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


This is an anonymous function that takes no input and returns a Char. To call it, assign it to a variable. It assumes that integers are 64-bit.

The ntoh function converts the endianness of the value passed to it from network byte order (big endian) to that used by the host computer. On big endian machines, ntoh is the identity function since there's no conversion to be done. On little endian machines, the bytes are swapped, so ntoh(5) == 360287970189639680. Which is also, perhaps more readably, equal to: 0000010100000000000000000000000000000000000000000000000000000000 in binary.

If we right bit shift the result of ntoh(5) by 55, we'll get 0 on big endian machines and 10 on little endian machines. Adding that to the character constant 'B', we'll get 'B' or 'L' for big or little endian machines, respectively.

Saved 5 bytes thanks to FryAmTheEggman and Dennis!

• For 32 bit you would have to change 55 to 23 (also the 5 in the 16 bit one should have been 7, my mistake). I think Dennis meant something like: ()->ntoh(5)>>55+'B'? – FryAmTheEggman Jul 28 '16 at 19:17
• f()='L'-ntoh(10)%16 and f()='L'-ntoh(10)&10 should work on all platforms. – Dennis Jul 28 '16 at 19:31

# PHP 5.6, 41 31 bytes (thx to isertusernamehere)

<?=unpack(S,"\x01\x00")[1]-1?B:L;

# PHP 7, 41 bytes

echo unpack('S',"\x01\x00")[1]-1?'B':'L';

Idea stolen from: https://stackoverflow.com/a/24785578/2496717

• You can save 10 bytes: <?=unpack(S,"\x01\x00")[1]-1?B:L;. – insertusernamehere Jul 28 '16 at 17:03

## Common Lisp, 27 bytes

Tested on SBCL and ECL. For a portable approach, one should use trivial-features.

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


The #+ notation is a read-time condition, that reads the next form only if the conditional expression evaluates to true. Here the condition is the whole #+big-endian text which means that the test is satisfied if the :big-endian keyword belongs to the *FEATURES* list (a list which contains among other things platform-specific information). The following expression is 'B, which is either read or skipped according to the outcome of the test. If your platform is big-endian and you write the above form in the REPL, it is exactly as if you wrote the following:

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


(NB.CL-USER> is the prompt)

A function's body is an implicit PROGN, meaning that only the evaluation of the last expression is returned. So the above actually returns symbol ̀B. If however the read-time condition evaluates to false, the form reads as if you wrote:

CL-USER>(lambda()'L)


... which simply returns symbol L.

• Snippets are not allowed; write full programs or functions instead. – Erik the Outgolfer Jul 29 '16 at 9:37
• @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Updated, thanks – coredump Jul 29 '16 at 10:25
• Note: Snippets are only allowed if explicitly permitted by the OP. – Erik the Outgolfer Jul 29 '16 at 10:38
• @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Could you provide a reference for this? There are other REPL answers over here and/or shell snippets and this meta post would suggest that REPL answers could be ok by default. Thanks. – coredump Aug 28 '16 at 6:59

## ARMv6 and later: 20 bytes machine code

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)


Untested, as I don't have a suitable machine to hand. Bit 9 of the CPSR gives the current load/store endianness.

• You can use a return from the function (BX lr, is it?) instead of putchar, because r0 is the proper register for returned result. – anatolyg Jul 31 '16 at 15:24
• Indeed, that (actually MOV pc,lr) was in one of my previous edits. However this fulfills the specification to print the letter, not just return it. – user1908704 Jul 31 '16 at 17:56
• I may be reading the reference wrong, but I think this can be done in the "thumb 2" instruction encoding. This would mean the first instruction remained 32 bits ("encoding T1" on page F7-2720 of the ARM v8 reference manual, which would make it 0xF3EF_8000); the second is also 32 bits (encoding the operand is a bit bizarre, but can be done with "i:imm3" set to 0010 and "imm8" to 00000010, which gives an overall instruction of 0xF010_2F02). Before the third instruction, we need to insert "ITE EQ" (0xBF0C) to control the conditions on the next two MOV instructions, which become 0x204C and ... – Jules Nov 7 '16 at 1:32
• ... 0x2042 (saving 2 bytes overall). Then the final BL instruction is a little difficult to represent because the bits of the address which we don't know end up scattered among the bits of the instruction we do know, but it is also a 32-bit encoding, so the result would be 18 bytes total (F3 EF 80 00 F0 10 2F 02 BF 0C 20 4C 20 42 F? ?? ?? ??). I believe this changes the architecture to ARMv8 and later, although it may work in ARMv7(?). – Jules Nov 7 '16 at 1:36

# Perl 5, 21 + 1 = 22 bytes

Run with perl -E.

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


Tested on amd64 (little-endian) and mips (big-endian).

• Is the -E flag really necessary in the byte count? You can just say you use Perl 5.10 (since the saycommand is available in this version) – Paul Picard Jul 28 '16 at 21:00
• @PaulPicard But use 5.10.0; is many more bytes! – Anders Kaseorg Jul 28 '16 at 21:08
• @PaulPicard Your point is wrong. Perl 5.10 requires the -E switch or the use statement for say. – Anders Kaseorg Jul 28 '16 at 21:26
• -E is "free" on PPCG. No need to add anything. – Ven Jul 29 '16 at 10:06
• (however -n and -p are not) – Ven Jul 29 '16 at 10:06

# R, 28 23 bytes

substr(.Platform$endian,1,1)  .Platform$endian returns big if run on big endian and little if on little. Here, using substr, it returns the first letter of the output, so either b or l.

As endian is the only object starting with an e contained in object .Platform we can reduce it thanks to partial matching to the following 23 bytes code:

substr(.Platform$e,1,1)  # Clojure, 46 44 bytes #(nth(str(java.nio.ByteOrder/nativeOrder))0)  This is a function that uses the Java builtin to get the endianness of the machine. Then get the string representation of it which will be either "LITTLE_ENDIAN" or "BIG_ENDIAN" and take the first character of whichever string is chosen and return that. Saved 2 bytes thanks to @cliffroot. • What is clojure really, is it lisp or java? – Leaky Nun Jul 28 '16 at 1:14 • @LeakyNun Maybe a practical LISP that works with Java? It's hard to say. – miles Jul 28 '16 at 1:16 • #(nth(str(java.nio.ByteOrder/nativeOrder))0) is 2 bytes shorter – cliffroot Jul 28 '16 at 7:50 # Ruby, 3130 chars. puts [1].pack("s")>"\01"??L:?B  Hmm, must be a better way. Count 5 characters less if the char need not to be output as I think other solutions omit printing. i.e. remove the "puts " part if you don't want anything printed. • If I remember correctly, after Ruby 1.9, you can use ?L and ?B in place of puts :L and puts "B" – Sherlock9 Jul 28 '16 at 14:26 • I think puts [76,66].pack("s")[0] will work. – Wayne Conrad Jul 28 '16 at 23:09 • @Sherlock9, thanks, one char less. @WayneConrad, Perhaps add your answer, I don't have a big endian machine at hand to test but on little endian it works. But changing like this does not work: puts [76,66].pack("s>")[0]. That means it is possible to not be working on big endian for some reason I don't understand well. But this one seems to work (derived from your solution) puts [19522].pack("s>")[0]. WDYT? I wonder if I can find some place to evaluate on big endian. – akostadinov Jul 29 '16 at 5:59 • Alas, I also lack a big-endian machine to test on. – Wayne Conrad Jul 29 '16 at 14:30 # Bash (and other unix shells), 32 (33) bytes First and second attempt: case echo|od in *5*)echo B;;*)echo L;;esac # portable [[ echo|od =~ 5 ]]&&echo B||echo L # non-portable  Thanks to Dennis, shorter version: od<<<a|grep -q 5&&echo L||echo B # non-portable echo|od|grep -q 5&&echo B||echo L # portable  The echo utility outputs a newline, with hex value 0A, and no other output. For <<<a it is 61 0A. The od utility, by default, interprets the input as two-byte words, zero-padded if the number of bytes is odd, and converts to octal. This results in the output of echo being interpred as 0A 00, which is converted to 005000 as big-endian or 000012 in little-endian. 61 0A becomes 005141 in little-endian and 060412 in big-endian. The full output of od also includes address and size data meaning we cannot use 0, 1, or 2 for the test. The command is well-defined to expose the system's endianness. From the standard: The byte order used when interpreting numeric values is implementation-defined, but shall correspond to the order in which a constant of the corresponding type is stored in memory on the system. ## Compatibility notes I am not certain if putting echo|od in backquotes with no double quotes around them [which results in a three-word argument to case] is supported on all systems. I am not certain if all systems support shell scripts with no terminating newline. I am mostly certain but not 100% of the behavior of od with adding the padding byte on big-endian systems. If needed, echo a can be used for the portable versions. All of the scripts work in bash, ksh, and zsh, and the portable ones work in dash. • None of the changes are necessary; just put one shell it works in in the language headet and you're set. – Dennis Jul 29 '16 at 20:15 • @Dennis I like doing that kind of analysis... though it's more fun if I do find something non-standard that gets a shorter answer in bash or zsh than the others. Maybe I'll see what can be done with [[ – Random832 Jul 29 '16 at 20:17 • Nothing wrong with the analysis. The last paragraph just sounded like you were uncertain if a shell-specific answer is valid... od<<<a|grep -q 5&&echo L||echo B should work in Bash and others. – Dennis Jul 29 '16 at 20:23 • I tested it in a big-endian VM, and echo|od prints 0000000\n005000\n0000001 as you expected. – Dennis Jul 30 '16 at 0:29 • @user17752 Because endianness doesn't affect the output of od -a. – Random832 Jul 30 '16 at 5:36 ## PHP, 16 bytes <?=pack(S,14)^B;  This uses two tricks not used in the two existing PHP answers: 1. The value passed to pack() or unpack() can be anything, not just 0 or 1. 2. The bitwise XOR operator (^) works on strings, and the result is only as long as the shorter string, avoiding the need for a string indexing or ternary operator. # Node, 42 bytes n=>require('os').endianness()[0]  Pro: there's a builtin. Con: property names are very long # PowerShell, 44 bytes [char](66+10*[BitConverter]::IsLittleEndian)  Character 66 is B, and 10 characters later is number 76, L. A Boolean value of "true" becomes 1 when cast to a number. BitConverter is a standard .NET class. # Racket, 35 28 bytes (if(system-big-endian?)'B'L)  'B or 'L respectively. Let me know if this is not specific enough :) # PHP, 22 bytes <?=ord(pack(S,1))?L:B;  ## Haskell (using GHC-only size-restricted numeric types), 75 bytes import Unsafe.Coerce import GHC.Int f="BL"!!fromEnum(unsafeCoerce 1::Int8)  (not tested on a big-endian architecture, but it seems like it ought to work!) ## K, 15 bytes  ("bl")@*6h$-8!
,"l"


Explanation;

    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


## Bash, 27 bytes

iconv -tucs2<<<䉌|head -c1


䉌 (U+424C) is encoded as three UTF-8 bytes: E4 89 8C.

It is assumed that iconv` uses the function from glibc and that a UTF-8 locale is used.