编写一个程序或函数,该程序或函数输出L
在小端架构上B
运行的if 或在大端架构上运行的if。小写输出l
还是b
可以的。
没有输入。
计分是代码高尔夫,因此字节最少的代码获胜。
编辑: 根据下面的评论,我澄清一下,该条目必须能够在两种体系结构上运行。
我相信只有一个答案会受到影响,并且该答案已明确表明确实如此。
B0 4C C3
,为mov al, 'L' / ret
或unsigned char f(){ return 'L'; }
,将是有效的x86答案。
编写一个程序或函数,该程序或函数输出L
在小端架构上B
运行的if 或在大端架构上运行的if。小写输出l
还是b
可以的。
没有输入。
计分是代码高尔夫,因此字节最少的代码获胜。
编辑: 根据下面的评论,我澄清一下,该条目必须能够在两种体系结构上运行。
我相信只有一个答案会受到影响,并且该答案已明确表明确实如此。
B0 4C C3
,为mov al, 'L' / ret
或unsigned char f(){ return 'L'; }
,将是有效的x86答案。
Answers:
import sys
exit(sys.byteorder[0])
sys.byteorder
是'little'
或'big'
(对于在不看代码的情况下阅读此句子的人,则[0]
表示第一个字符)。
L
和B
(或小写变体),而不是整个单词。
sys.byteorder[0]
,即的第一个字符byteorder
。
a=66<<24|76;f(){puts(&a);}
假定32位int
和ASCII字符。在amd64(小端)和mips(大端)上进行了测试。
00000000: 613d 2742 0000 4c27 3b66 2829 7b70 7574 a='B..L';f(){put
00000010: 7328 2661 293b 7d s(&a);}
由feersum建议。多字符常量的值取决于实现,但这似乎在GCC中有效。在相同的架构上进行了测试。
a='B\0\0L';
将\0
s替换为空字节。
_=>"BL"[new Int8Array(Int16Array.of(1).buffer)[0]]
我不知道是谁决定让TypedArray对象公开解释器的本机字节序是一个好主意,但是到了。
1个字节,感谢@algmyr和@owacoder。
main(a){printf(*(char*)&a?"L":"B");}
main(a){putchar(66+10**(char*)&a);}
main(a){putchar("BL"[*(char*)&a]);}
学分在这里。
由于我没有大端机,因此未经测试。
main
函数?
1
因为没有输入(程序名称始终作为第一个参数)
main(a){putchar("BL"[*(char*)&a]);}
。
main(char a){putchar("BL"[a]);}
。
{B,L}[[$ByteOrdering]]
这可能会违反一些关于不使用内置函数的规则,但是我对替代项并不十分感兴趣。
&
使其成为一个函数。(但是在什么构成“程序”方面可能存在分歧。)
再长一个字节,但是无论如何这里是:
f(){putchar(htons(19522));}
1001100 01000010
(空格分隔字节)。现在,如果您占用每个字节,将其转换回以10为基数并检查ASCII表,您将看到此字节序列等效于LB
。htons
将执行其操作,并且putchar
只会打印LSB。在大端系统中,B
小端系统htons
将翻转字节,因此LSB为L
。
19522
与'LB'
编译器警告和-1字节。
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
现在,它像这样:
rlwinm
提取物只是位:它需要在GPR0的值,- [R otates 升由1所代替EFT(使得现在是在位置0)和米与1(由那些31,31所产生的掩模要求它2); 结果存入GP寄存器3;'B'
)(10 之间的差别'L'
和'B'
)()->(""+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我无法使用big-endian机器。
char e(){return(""+java.nio.ByteOrder.nativeOrder()).charAt(0);}
char e(){return(""+java.nio.Bits.byteOrder()).charAt(0);}
()->(""+java.nio.ByteOrder.nativeOrder()).charAt(0);
C#在这一方面具有惊人的竞争力。
char e=>System.BitConverter.IsLittleEndian?'L':'B';
感谢Groo提供的C#6语法。
60个字节:
char e(){return System.BitConverter.IsLittleEndian?'L':'B';}
char e=>System.BitConverter.IsLittleEndian?'L':'B';
当然,这个(以及Java答案)实际上并不会输出该值。
()->ntoh(5)>>55+'B'
这是一个匿名函数,不接受任何输入并返回Char
。要调用它,请将其分配给变量。假定整数是64位。
该ntoh
函数将传递给它的值的字节序从网络字节顺序(大字节序)转换为主机使用的字节序。在大型字节序计算机上,ntoh
由于无需进行转换,因此是身份函数。在小字节序计算机上,字节被交换,所以ntoh(5) == 360287970189639680
。也可能更可读地等于:0000010100000000000000000000000000000000000000000000000000000000
二进制。
如果将结果右移ntoh(5)
55,则在大字节序计算机上将得到0,在小字节序计算机上将得到10。并称,在字符常量'B'
,我们会得到'B'
或'L'
对或大或小端机,分别。
多亏了FryAmTheEggman和Dennis,节省了5个字节!
()->ntoh(5)>>55+'B'
?
f()='L'-ntoh(10)%16
并f()='L'-ntoh(10)&10
应可在所有平台上使用。
<?=unpack(S,"\x01\x00")[1]-1?B:L;
echo unpack('S',"\x01\x00")[1]-1?'B':'L';
<?=unpack(S,"\x01\x00")[1]-1?B:L;
。
在SBCL和ECL上测试。对于一种可移植的方法,应该使用一些琐碎的功能。
(lambda()'L #+big-endian'B)
的#+
符号是一个读取时间条件,即读出下一表格仅当条件表达式评估为真。这里的条件是#+big-endian
全文,这意味着如果:big-endian
关键字属于*FEATURES*
列表(包含平台特定信息等在内的列表),则满足测试条件。以下表达式是'B
,根据测试结果可以读取或跳过。如果您的平台是big-endian,并且您在REPL中编写了以上表格,则就像您编写了以下内容一样:
CL-USER>(lambda()'L 'B)
(CL-USER>
提示。)
函数的主体是一个隐式PROGN
,意味着仅返回最后一个表达式的求值。所以上面的实际返回符号B
。但是,如果读取时间条件评估为false,则该表单的读取就像您编写的一样:
CL-USER>(lambda()'L)
...只是返回symbol L
。
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)
未经测试,因为我没有合适的机器。CPSR的位9给出了当前的加载/存储字节序。
BX lr
,是吗?)的返回值代替putchar
,因为这r0
是返回结果的正确寄存器。
用运行perl -E
。
say ord pack(S,1)?L:B
在amd64(小端)和mips(大端)上进行了测试。
-E
字节计数中是否真的需要该标志?您可以说您使用的是Perl 5.10(因为say
该版本提供了此命令)
use 5.10.0;
还有更多字节!
-E
switch或use
语句say
。
-E
在PPCG上“免费”。无需添加任何内容。
-n
并-p
没有)
#(nth(str(java.nio.ByteOrder/nativeOrder))0)
这是一个使用Java内置函数获取计算机字节序的函数。然后获取它的字符串表示形式,该字符串表示形式将为"LITTLE_ENDIAN"
或,"BIG_ENDIAN"
并采用所选字符串中的第一个字符并将其返回。
由于@,节省了2个字节悬崖根。
#(nth(str(java.nio.ByteOrder/nativeOrder))0)
短2个字节
puts [1].pack("s")>"\01"??L:?B
嗯,一定是更好的方法。如果不需要输出char,请少计算5个字符,因为我认为其他解决方案可以省略打印。例如,如果您不想打印任何内容,请删除“放置”部分。
?L
和?B
代替 puts :L
和puts "B"
puts [76,66].pack("s")[0]
会起作用。
puts [76,66].pack("s>")[0]
。这意味着出于某种我不太了解的原因,可能无法从事大端字节排序。但是,这似乎是可行的(源自您的解决方案)puts [19522].pack("s>")[0]
。WDYT?我想知道是否可以找到一些在大端上进行评估的地方。
第一次和第二次尝试:
case `echo|od` in *5*)echo B;;*)echo L;;esac # portable
[[ `echo|od` =~ 5 ]]&&echo B||echo L # non-portable
多亏了丹尼斯(Dennis),缩短了版本:
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
大端。OD的完整输出也包括地址和尺寸数据意味着我们不能使用0
,1
或2
用于测试。
该命令定义明确,可以公开系统的字节序。从标准:
解释数值时使用的字节顺序是实现定义的,但应与相应类型的常量存储在系统内存中的顺序相对应。
我不确定是否在所有系统上都支持echo|od
在反引号中使用双引号将其引起来的三字参数case
。我不确定是否所有系统都支持不带换行符的shell脚本。我大都可以肯定,但是在big-endian系统上添加padding字节并不是od的100%。如果需要,echo a
可用于便携式版本。所有脚本都可以在bash,ksh和zsh中使用,而可移植脚本则可以在破折号中使用。
[[
od<<<a|grep -q 5&&echo L||echo B
是否可以在Bash和其他版本中使用。
echo|od
打印0000000\n005000\n0000001
。
od -a
。
<?=ord(pack(S,1))?L:B;
("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