我有以下声明
iex(5)> a = <<3>>
<<3>>
iex(6)> b = <<a::binary>>
<<3>>
第一行,我创建了一个值为3的二进制文件。在第三行我希望shell显示00000011而不是3.我知道首先创建一个二进制文件(1.line)然后再转换为二进制文件没有意义。但我期待shell显示00000011而不是3。
当二进制像浮动一样
iex(7)> a = << 5.3 :: float >>
<<64, 21, 51, 51, 51, 51, 51, 51>>
我不明白,为什么它会告诉我这个数字?
答案 0 :(得分:4)
Binary是内存中的字节序列。打印的表示符合此定义。打印输出中的每个数字都在0到255之间(这些数字可以表示所有可能的字节值)。
二进制文件是一种很酷且简单的方法,可以解析和编码要通过网络发送到外部系统的协议或其他消息。例如,这段代码解析ip协议:
<< protocol_version :: size(4),
size_in_words :: size(4),
tos :: size(8),
total_length :: size(16),
identifier :: size(16),
flags :: size(3),
fragment_offs :: size(13),
ttl :: size(8),
protocol :: size(8),
header_checksum :: size(16),
src_ip :: size(32),
dst_ip :: size(32),
options :: size(32),
data :: binary >> = bits
您可以匹配二进制文件的不同部分。 size
以位为单位指定。最后一部分可以没有大小,但它需要可以被8整除(它必须是n个完整字节)。
不太复杂的例子可能是128号,二进制为10000000。
iex(1)> bin = <<128>>
<<128>>
iex(2)> <<a::size(2), b::size(6)>> = bin
<<128>>
iex(3)> a # a matched bits 10, which is 2
2
iex(4)> b # b matched bits 000000 which is 0
0
可以使用相同的语法从部件创建二进制文件。允许重用变量a和b,但将它们放在不同的地方。
iex(5)> anotherbin = <<a::size(5), b::size(3)>>
<<16>>
现在第一部分是00010,第二部分是000,它给出00010000,这是16。另一件事是你可以用浮点数等整数来创建二进制文件,所以
iex(6)> a = << 5.3 :: float >>
<<64, 21, 51, 51, 51, 51, 51, 51>>
创建另一个具有浮点值编码的二进制文件。您现在可以通过网络发送它并在另一侧解码它。所以它与你的想法相反。它不是二进制的float,而是float作为二进制文件。
要实际查看内容的二进制表示,请尝试使用来自不同模块的to_string
方法。它们具有可选参数,您可以在其中打印输出。
iex(7)> Integer.to_string(128, 2)
"10000000"
还有一个问题。 Elixir中的字符串实际上是二进制文件。 shell检查所有字节是否都是可打印字符。如果是,则将它们打印为字符串
iex(20)> <<100>>
"d"
如果需要,您可以强制IO.inspect
打印二进制文件作为字节或字符串列表:
iex(29)> IO.inspect <<100>>, [{:binaries, :as_binaries}]
<<100>> #this is what IO.inspect printed
"d" #this is a return value, which is the same, but printed as string
如果强制将不可打印的字符解释为字符串,则会对其进行转义:
iex(31)> IO.inspect <<2>>, [{:binaries, :as_strings}]
"\x02" #this is what IO.inspect printed
<<2>> #return value printed by shell