Elixir字符串(二进制)转十进制:原理解析与一步实现方法
把Elixir二进制字符串转成十进制整数:原理与一步实现方案
首先,咱们来拆解你现在用的方法为什么能生效,然后再看看怎么一步到位实现~
现有方法的原理分析
你当前的实现代码是这样的:
<<104, 101, 108, 108, 111>> |> Base.encode16() |> Integer.parse(16)
咱们一步步拆解逻辑:
- 二进制转十六进制字符串:
Base.encode16/1会把二进制里的每个字节转换成两位十六进制字符。比如<<104>>(对应字符'h')会变成"68",因为104的十六进制表示是0x68。所以整个<<104,101,108,108,111>>转成十六进制字符串就是"68656C6C6F"。 - 十六进制字符串转十进制整数:
Integer.parse/2第二个参数指定基数为16,它会把这个长十六进制字符串当成一个完整的十六进制数解析,转换成对应的十进制整数。"68656C6C6F"作为十六进制数,转成十进制就是448378203247,也就是你拿到的结果。
本质上,这个方法是把二进制的所有字节拼接成一个大的十六进制数,再转成十进制——相当于把二进制当成大端字节序的无符号整数来处理,这也是结果是那个大数字的核心原因。
一步实现的方案
其实Elixir里可以直接用:binary.decode_unsigned/2函数一步完成转换,完全不需要绕十六进制的弯路。这个函数专门用来把二进制解析成无符号整数,默认就是大端字节序(和你之前的方法逻辑完全一致):
:binary.decode_unsigned(<<104, 101, 108, 108, 111>>) # 输出:448378203247
如果需要指定字节序,还可以传第二个参数,比如:little表示小端字节序,但你之前的方法是大端逻辑,所以默认参数就刚好匹配需求。
要是你想手动实现这个逻辑加深理解,也可以用递归遍历二进制的每个字节,逐步计算权重累加:
defmodule BinaryToDecimal do def convert(<<byte::8, rest::binary>>), do: byte * :math.pow(256, byte_size(rest)) |> round() + convert(rest) def convert(<<>>), do: 0 end BinaryToDecimal.convert(<<104, 101, 108, 108, 111>>) # 输出:448378203247
这个逻辑和:binary.decode_unsigned完全一致:每个字节的权重是256的n次方(n是后面剩余的字节数),累加所有字节的加权值就是最终的十进制整数。
内容的提问来源于stack exchange,提问作者RobStallion
相关产品推荐
相关产品推荐

