【问题标题】:Unsigned Int in JavaJava中的无符号整数
【发布时间】:2011-05-25 20:20:18
【问题描述】:

我正在尝试实现一个现有的网络协议,该协议大量使用 Java 不支持的无符号数据类型。我目前所做的是针对每种数据类型,选择下一个较大的数据类型,以便无符号数可以适合正数区域,然后使用字节移位来获得所需的效果。由于这很容易出错,而且对于 unsigned long 开始,我必须使用比扩展类型重得多的 BigInteger,我想知道是否有更好的方法来实现这一点?

【问题讨论】:

    标签: java networking protocols unsigned


    【解决方案1】:

    根据您的操作,您可以将 long 视为 64 位值,将 int 视为 32 位值。大多数操作 esp readInt/Long writeInt/Long 通过忽略符号来工作。

    您能否举例说明您对这些数字执行的操作,也许我们可以建议如何在不扩展类型的情况下做同样的事情。

    例如,++、--、+、-、*、==、!=、> 你可以替换 >>>

    假设有符号值的是 /、%、>、>=、

    例如

    long unsignedA = 
    long unsignedB = 
    boolean greater = unsignedA + Long.MIN_VALUE > unsignedB + Long.MIN_VALUE
    

    编辑:为什么会这样?部分原因是 java 没有上溢/下溢异常。

    例如

    byte unsignedA = 0;
    unsignedA--; 
    // unsignedA == FF, is this -1 or 255? Java assumes the former but you assume the later
    
    byte unsignedB = unsignedA * unsignedA;
    // unsignedB is -1 * -1 = 1 or (byte) (255*255) = (byte) 65525 = 1.
    

    【讨论】:

    • 嗯,这听起来很有希望,我希望只创建一个 InputStream 并从那里按预期使用值,而不是在程序中拖动它们。问题是它们在很大程度上代表了 IP 地址、版本号(在 >、= 上非常重要)、加密哈希(可能没有问题)和时间戳(在比较上也很重要)。
    • 对于IP地址,您需要使用baising技巧或延长。对于长时间戳,如果它们以毫秒为单位,您应该能够假设它们在 0 和 Long.MAX_VALUE 之间。您的版本号也使用最高位吗?你能举一个例子吗? (如果是这样,您还需要进行比较)
    • 如果您从公元前 1 年开始(没有 0 年),则签名的长毫秒时间戳限制为 292,471,208 年,
    • 遗憾的是我无法更改协议本身,但你是对的,我可以忽略时间戳中的更高位(它们从 01.01.1970 开始以秒为单位......)。是的,设计协议的人做了一些非常糟糕的选择:-)
    • @cdecker,所以如果你忽略顶部几秒钟,你仍然可以去到 2930 亿年,因为太阳只剩下 60 亿年的生命...... ;) 将日期偏移到 1970 年相当没有意义。 ;) 自公元前 1 年以来,他可能没有微秒,我怀疑你仍然不会有问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2013-08-29
    • 1970-01-01
    • 2010-09-19
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多