java - 将十进制转换为二进制,任意基数

标签 java

长期程序员,业余爱好者。

我们有一个 80 位帧(80 个 1/0-s)来编码/解码铱星/网络通信。为了将所有参数变成 80 位(纬度、经度、通量等),位的对齐方式不是 2、8、16 等。它们对齐为 3 位、1、7、8 等。精通 C 语言的位操作者知道掩码/移位操作,但我不知道。经过几天的谷歌搜索,我得到了一个简单的例子(BigInteger? String oddString = Integer.toString(number,odd_radix)? char[] Buf?)。有没有直接的方法或一个好的链接供我使用示例?

最佳答案

在某种程度上,这实际上非常简单。主要问题是您有 80 位,并且没有一种“自然”的方式将其表示为 Java 中的整体 block 。

有 BitSet 类,但它并没有真正提供您想要的(即“我想要 3 位 7、8 和 9 的值作为整数”或相反“设置从 bit 开始的 3 位值” 7 英寸)。

如果您的表示足够大,则屏蔽和移动很简单。如果您的位集少于 32,那么一个简单的 int 就足够大了。不幸的是,你的是80位,甚至long(64位)也不够长。

但是,如果运气好(没有使用铱星有效负载的经验,有效负载在任何合理的边界上破裂(即有一组字段在 32 位屏障或 64 位屏障上结束),那么您可以将有效负载分解为单独的“ block ”,然后将它们单独处理和处理位字段集,然后掩码和移位就很容易了。

另一个问题是 Java 没有 unsigned 数据类型,但如果您不需要尝试访问整个数据,那么这就不是什么问题了。最后,无论有符号还是无符号,32 位就是 32 位。

将字节转换为intslongs 非常简单。您需要搜索它,但这很简单。

但是假设您的有效负载可以大致分解为 48 位容器和 32 位容器。这意味着不存在跨越 48 位标记的字段。这适用于 8 位标记上的任何边界。

基本上,您会将 48 位、6 字节数组转换为 long。

long l = convertFromBytes(sixByteArrayOfData);

然后移动和遮蔽就很容易了。您只需以二进制形式创建表示字段的常量,然后将它们转换为十六进制即可。

那么,假设您想要位 15、16、17、18。

用二进制表示:

00000000 00000000 00000000 00000111 10000000 00000000

但这只有 48 位。所以,把它补起来

00000000 00000000 00000000 00000000 00000000 00000111 10000000 00000000

将其转换为十六进制:

00 00 00 00 00 07 80 00

将其设为单个十六进制常量:

long mask15to18 = 0x0000000000078000

现在你可以屏蔽它:

int fieldValue = l & mask15to18;

然后你移动它。由于我们使用的是第 15 位,因此我们将其移位 15 次。

fieldValue = fieldValue >> 15;

您建立了一系列掩码和类次来拉出您的字段。

要将它们添加回来,您只需再次移动掩码,然后将其添加到您的最终值。

newValue = newValue + ((fieldValue << 15) & mask15to18)

您需要屏蔽以消除任何符号扩展,因为您不使用无符号值。

您对每个字段都执行此操作,直到您有一个解码和编码方法,可以将有效负载从 10 字节数组转换为您通常可以使用的 java 对象。

它适用于 int、byte、long。只需要在有效负载中找到字段不跨越 8 位边界的点。这就是让它变得更容易的原因。

关于java - 将十进制转换为二进制,任意基数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24714819/

相关文章:

Java 日期比较失败

Java 日期比较 : Dates in different formats

java - 具有自定义标题的 Android 应用程序的 3 点设置菜单

java - 确定评估整数规则时的互斥

java - 从 lambda 内部修改局部变量

java - SpringBoot 集成测试 Sybase 和 Testcontainers

java - 如何将HashMap显示为DataTable

java - 如何在 jtable 中设置相同的颜色并在 java 中将不同的颜色设置为不同的结果

java - 将类实例保存在数据库中

Java 和统一码