【问题标题】:Why can't I convert signed int to unsigned long为什么我不能将signed int 转换为unsigned long
【发布时间】:2015-12-15 16:51:23
【问题描述】:

我正在从 Java 文件中读取数值数据:

一个字节长度的数据代表一个unsigned byte 两个字节长度的数据代表一个unsigned short 四字节长度的数据代表一个unsigned int

但是因为 Java 7 没有无符号类型,我需要使用 short/integer 来表示整个字节值范围,integer 来表示短值,我假设 @987654327 @ 表示一个整数值。

但是我在表示整数值时遇到了问题

我有这三种方法:

 public class Utils 
 { 
    public static int u(short n)
    {
        return n & 0xffff;
    }


    public static int u(byte n)
    {
        return n & 0xff;
    }

     public static long u(int n)
    {
        return n & 0xffffffff;
    }
}

三个测试用例,但只有前两个测试用例有效:

public void testByteToUnsignedIntConversion()
    {
        byte maxByte = (byte)0xff;
        int  maxNotConverted = maxByte;
        int  maxConverted    = Utils.u(maxByte);
        System.out.println(maxConverted + ":" + maxNotConverted);
        assertEquals(255,maxConverted);
    }

    public void testShortToUnsignedIntConversion()
    {
        short maxShort = (short)0xffff;
        int  maxNotConverted = maxShort;
        int  maxConverted    = Utils.u(maxShort);
        System.out.println(maxConverted + ":" + maxNotConverted);
        assertEquals(65535,maxConverted);
    }

    public void testIntToUnsignedLongConversion()
    {
        int maxInt = 0xffffffff;
        long  maxNotConverted = maxInt;
        long  maxConverted    = Utils.u(maxInt);
        System.out.println(maxConverted + ":" + maxNotConverted);
        assertEquals(4294967296l,maxConverted);
    }

我误会了什么?

【问题讨论】:

  • 首先,你明白& 0xfff...fff这些东西的意义吗?我想你的误解从这里开始。
  • 无论如何,像这样修复它:return (long) n & 0xffffffff;.
  • 或者只是把常数变长:n & 0xffffffffL
  • 啊在所有这些方法中 n 隐含地变成一个整数,然后 0xff 屏蔽掉 al 但最低字节, 0xff0xff 屏蔽除了最低两个字节之外的所有字节,最后一个失败,因为我需要早在掩蔽之前,但你的权利 Marko 我不太明白
  • @MarkoTopolnik 你的修复对我不起作用,

标签: java io binary hex


【解决方案1】:

Guava 提供了无符号值的辅助方法——UnsignedIntsUnsignedLongs 等(有关更多信息,请参阅their wiki),而不是自己滚动,Java 8 中也有内置方法可供使用- parseUnsignedIntdivideUnsigned

【讨论】:

  • 谢谢,但现在因为这是一个公共库,我不能迁移到 Java 8,我不想添加 guava 依赖项,希望将来会这样做
【解决方案2】:

除非另有说明,否则按位和 (&) 将操作数作为整数处理。这就是它使用 byte 和 short 的原因,因为这些方法返回一个整数。因此,由于您希望结果是一个长值以将其作为无符号值处理,因此您应该使用整数最大值掩码(即 2^32-1 或 0xFFFFFFFF)并将其转换为长值。长常量在java中应该以L结尾,所以修改如下:

public static long u(int n)
{
    return n & 0xffffffffL;
}

如果您需要对无符号值进行算术运算,而您使用的 java 版本无关紧要,我建议您使用 java 8,因为它具有 Long、Integer、Byte 和 Short 类中的方法做这样的无符号操作。

【讨论】:

  • '按位和 (&) 将操作数作为整数处理' - 这是我不明白的关键部分,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多