Java signed unsigned long 无符号数和有符号数之间的转换测试

这篇博客探讨了在Java中如何处理无符号64位数字,特别是当最高位被用作符号位时。作者展示了如何将64个1的无符号long数值转换为Java能表示的long,并提供了两种不同的转换方法。此外,还讨论了如何将长整型数值转换为无符号形式,以及涉及到的位运算和BigDecimal的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 中的long类型是64位,即64个二进制位在一起来表示一个数,但是64个bit位中,最顶上1个bit是标志位,用来表示正负数的,所以,他能表示的最大的正数,就是63个1,带上最高位是0,然而其他的平台是可以把64位全部用来表示数字的。没有把最高位当作标记位来用。怎么把这个无符号的数字变成Java能表示的long呢?

package com.lxk.jdk.common;

import org.junit.Test;

import java.math.BigDecimal;

/**
 * @author LiXuekai on 2021/4/28
 */
public class LongTest {

    /**
     * 无符号64个1 unsigned long 数字
     */
    private static final String s = "18446744073709551615";

    @Test
    public void MaxAndMin() {
        outLongInfo(Long.MAX_VALUE);
        outLongInfo(Long.MIN_VALUE);
    }

    @Test
    public void test() {
        // 大于MAX,是无符号正数,但,还是64位的。
        outLongInfo(unsigned2Long1(s));
        outLongInfo(unsigned2Long2(s));

        System.out.println(longParseUnsigned(-216172773253120239L));
        System.out.println(longParseUnsigned(-1));
    }

    /**
     * 打印long的 value 二进制value 二进制value长度
     *
     * @param aLong java long value
     */
    private void outLongInfo(long aLong) {
        System.out.println("              long value is \t" + aLong);
        System.out.println("       long binary value is \t" + Long.toBinaryString(aLong));
        System.out.println("long binary value length is \t" + Long.toBinaryString(aLong).length());
    }

    /**
     * 方法1:unsigned long 2 signed long
     *
     * @param s unsigned long string
     */
    private long unsigned2Long1(String s) {
        return Long.parseUnsignedLong(s);
    }

    /**
     * 方法2:unsigned long 2 signed long
     *
     * @param s unsigned long string
     */
    private long unsigned2Long2(String s) {
        return new BigDecimal(s).longValue();
    }

    /**
     * long转成无符号数
     */
    public static BigDecimal longParseUnsigned(long value) {
        if (value >= 0) {
            return new BigDecimal(value);
        }
        // 按位与操作,就是把负数给转成相应的正数,比如-10 转成 10
        long lowValue = value & Long.MAX_VALUE;
        // 然后再左移 1 位,然后在最低位 + 1 。跟下面的 dd() 一样的逻辑。
        return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1));
    }

    @Test
    public void dd() {
        // 乘以2,相当于左移 1 位,最后一位是0,然后再加个1,就64个1了。
        BigDecimal multiply = new BigDecimal(Long.MAX_VALUE).multiply(new BigDecimal(2));
        System.out.println("Long.MAX_VALUE * 2 = " + multiply.toPlainString());
        BigDecimal subtract = multiply.add(new BigDecimal(1));
        System.out.println("Long.MAX_VALUE * 2 + 1 = " + subtract.toPlainString());
        System.out.println("64 个 1 的 无符号数 = " + s);
    }
}

运行结果截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值