0 问题描述

  • 经典问题:超出Java Long型(8字节/64位)的二进制比特流数据如何进行大数的数值计算?

近期工作上遇到了这个问题:需要将一个无符号数、且位长>=8字节(等于8字节时,首位bit为1,其他bit不全为0)的二进制字符串转为Java****对象(原始整数),进行整型运算、或浮点数运算

浮点运算的思路:result = 原始整数 * 精度 + 偏移量

  • 解决思路:将二进制字符串转为byte数组,再转为BigInteger大整型数。如果基于进行浮点运算时,可将 BigInteger 大整型数对象再转为 BigDecimal。

new BigDecimal v = new BigDecimal(new BigInteger(xxx))

1 解决过程示例

  • 二进制数据:"1100000001000000110010110000000000000000000000000000000000000000" (需考虑————情况1:作为有符号数情况2:作为无符号数

16进制:0xc040cb0000000000L

11000000
01000000
11001011
00000000
00000000
00000000
00000000
00000000

1.1 测试用例1:无符号数、且位长>=8字节(等于8字节时,首位bit为1,其他bit不全为0)的情况

    /** 针对 长度为 64 bit、无符号数 的CAN信号,且第1位为1的情况 :使用 BigInteger
* @description Java中没有内置的无符号8字节整数类型,但是可以使用 `java.math.BigInteger` 类来处理任意大的整数值,包括无符号整数
* @refernce-doc
**/
public static void unsigned8BytesDataTest(){
// 一个8字节的无符号整数
long longValue = 0xc040cb0000000000L; //0x10000000000000000L;
String longStr = "c040cb0000000000";//canFrameContent
// 转为二进制字符串
String binStr = BytesUtil.hexStringToBinaryString(longStr);
System.out.println("binStr: " + binStr);//1100000001000000110010110000000000000000000000000000000000000000 // 将无符号长整数转换为 BigInteger | 方式1: BigInteger
BigInteger value = toUnsignedBigInteger(longValue);
System.out.println("value : " + value);//1385 3295 6546 5208 4224 //二进制字符串转Java数据对象 | 测验 Long.parseLong(binStr , 2) | 若没有报错,则说明OK
BigInteger value2 = toUnsignedBigInteger(binStr);
System.out.println("value2 : " + value2);//1385 3295 6546 5208 4224 //二进制字符串转Java数据对象 | 测验 Long.parseLong(binStr , 2) | 若没有报错,则说明OK
Long value3 = Long.parseLong(binStr, 2);
System.out.println("value3 : " + value3);//报错信息如下
// Exception in thread "main" java.lang.NumberFormatException: For input string: "1100000001000000110010110000000000000000000000000000000000000000"
// at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
// at java.lang.Long.parseLong(Long.java:592)
// at ParseTest.unsigned8BytesDataTest(ParseTest.java:213)
// at ParseTest.main(ParseTest.java:29)
}

1.2 测试用例2:有符号数、且位长>=8字节(等于8字节时,首位bit为1,其他bit不全为0)的情况

    /**
* 有符号数、8字节
* 最终目标: 二进制字符串 转 Java 数据对象
*/
public static void signed8BytesDataTest(){
// 一个8字节的无符号整数
long longValue = 0xc040cb0000000000L; //0x10000000000000000L;
String longStr = "c040cb0000000000";//canFrameContent
// 转为二进制字符串
String binStr = BytesUtil.hexStringToBinaryString(longStr);
System.out.println("binStr: " + binStr);//1100000001000000110010110000000000000000000000000000000000000000 // 将有符号长整数转换为 BigInteger | 方式1: BigInteger
BigInteger value = toUnsignedBigInteger(longValue);
System.out.println("value : " + value);//-459 3448 4190 5746 7392 //二进制字符串转Java数据对象 | 测验 Long.parseLong(binStr , 2) | 若没有报错,则说明OK
BigInteger value2 = toUnsignedBigInteger(binStr);
System.out.println("value2 : " + value2);//1385 3295 6546 5208 4224 //二进制字符串转Java数据对象 | 测验 Long.parseLong(binStr , 2) | 若没有报错,则说明OK
Long value3 = Long.parseLong(binStr, 2);
System.out.println("value3 : " + value3);//报错信息如下
// Exception in thread "main" java.lang.NumberFormatException: For input string: "1100000001000000110010110000000000000000000000000000000000000000"
// at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
// at java.lang.Long.parseLong(Long.java:592)
// at ParseTest.signed8BytesDataTest(ParseTest.java:241)
// at ParseTest.main(ParseTest.java:30)
}

1.X 工具方法:toUnsignedBigInteger(long unsignedLong/String binStr)

    private static BigInteger toUnsignedBigInteger(long unsignedLong) {
// 将无符号的8字节长整数转换为字节数组
byte[] bytes = ByteBuffer.allocate(8).putLong(unsignedLong).array(); // 使用字节数组创建BigInteger
return new BigInteger(1, bytes);
} /** 二进制字符串 **/
private static BigInteger toUnsignedBigInteger(String binStr) {
byte[] bytes = null;
try {
// 将无符号的8字节长整数转换为字节数组
bytes = BytesUtil.binaryStringToBinaryArray(binStr);
} catch (Exception exception) {
log.error("Fail to convert as big integer!binStr : {}, exception : {}", binStr, exception);
} // 使用字节数组创建BigInteger
return new BigInteger(1, bytes);
}

X 参考文献

[Java SE] 经典问题:超出Java Long型(8字节/64位)的二进制比特流数据如何进行大数的数值计算?的更多相关文章

  1. 【Java SE】如何用Java实现直接选择排序

    摘要:直接选择排序属于选择排序的一种,但是它的排序算法比冒泡排序的速度要快一些,由于它的算法比较简单,所以也比较适合初学者学习掌握. 适宜人群:有一定Java SE基础,明白Java的数据类型,数组的 ...

  2. 【Java SE】如何用Java实现插入排序

    摘要:前面三期分别写了三篇简单排序的算法,今天来讲一点稍微难一点的排序算法-----插入排序. 基本思想: 设n个数据已经按照顺序排列好(假定从小排到大). 输入一个数据x,将其放在恰当的位置,使其顺 ...

  3. 【Java SE】如何用Java实现反转排序

    摘要:反转排序是将原先已经排序好了的重新排序,是原来的数组元素的顺序反转过来.假设原来的数组顺序是{6,5,4,3,2,1},反转之后的顺序就是{1,2,3,4,5,6}.这个排序的算法不是很难,代码 ...

  4. Java SE 6 新特性: Java DB 和 JDBC 4.0

    http://www.ibm.com/developerworks/cn/java/j-lo-jse65/index.html 长久以来,由于大量(甚至几乎所有)的 Java 应用都依赖于数据库,如何 ...

  5. 【Java SE】如何用Java实现冒泡排序

    摘要: 作为一名Java开发工程师,手头如果不会几个常见的排序算法,怎么可能经过笔试题这一关呢.据我所知,许多大型的公司的笔试题都有排序题,那我们先从最简单的排序:冒泡排序开始,以后几篇博客将继续更新 ...

  6. [零基础学JAVA]Java SE基础部分-01. Java发展及JDK配置

    转自:http://redking.blog.51cto.com/27212/114976 重点要会以下两个方面: 1. 抽象类与接口 2. API==>类集 这是两个最重要部分,这两个部分理解 ...

  7. Java SE基础知识

    Java SE面试题 目录 Java SE基础 基本语法 数据类型 关键字 面向对象 集合 集合类概述 Collection接口 List Set Map Java SE基础 基本语法 数据类型 Ja ...

  8. java SE 入门之八大内置基本类型(第二篇)

    本文采用eclipse 工具演示,如果您对eclipse 工具不了解,请先学习下 eclipse 工具的使用,这个里面只是简单的介绍下输出和注释: 安装完成eclipse 以后,双击进入 后一次点击 ...

  9. Java复习总结(二)Java SE 面试题

    Java SE基础知识 目录 Java SE 1. 请你谈谈Java中是如何支持正则表达式操作的? 2. 请你简单描述一下正则表达式及其用途. 3. 请你比较一下Java和JavaSciprt? 4. ...

  10. Java SE、Java EE、Java ME

    Java SE(Java Platform,Standard Edition).Java SE 以前称为 J2SE.它允许开发和部署在桌面.服务器.嵌入式环境和实时环境中使用的 Java 应用程序.J ...

随机推荐

  1. Hibernate-Validator扩展之自定义注解

    一.Hibernate-Validator介绍 ​ Hibernate-Validator框架提供了一系列的注解去校验字段是否符合预期,如@NotNull注解可以校验字段是否为null,如果为null ...

  2. 4、zookeeper的事件监听机制

    watcher概念 https://zookeeper.apache.org/doc/r3.4.14/zookeeperProgrammers.html#sc_WatchRememberThese z ...

  3. 使用Mockito与Squaretest进行单元测试.

    项目开发过程中,不少公司都要求写单元测试的代码,可以提高代码的质量,并且可以减少出现BUG的概率. 对于中小型公司来说,对单元测试不做硬性要求,不写最好.因为还是需要一定的工作量,在保证代码质量和性能 ...

  4. 【数据结构】哈夫曼树与哈夫曼编码(Huffman Encoding)

    一.背景 编码是信息处理的基础(重新表示信息). 普通的编码是等长编码,例如7位的ASCIL编码,对出现频率不同的字符都使用相同的编码长度.但其在传输和存储等情况下编码效率不高. 可使用不等长编码,来 ...

  5. 从一线方案商的角度来看高通QCC3020芯片

    写在前面的话   QCC3020的推出已经有一段时间了.在蓝牙音频的圈子里,属于家喻户晓的芯片了.再加上高通的大力宣传和一些顶尖级产品的使用,可以说,它是高通在吸收CSR的技术之后,着力推出的最具竞争 ...

  6. mybatis-plus详细使用教程

    mybatis-plus使用教程 欢迎关注博主公众号「Java大师」, 专注于分享Java领域干货文章http://www.javaman.cn/jszw/mybatis-plus 什么是Mybati ...

  7. Django:Nginx 启动,无法加载样式,无法加载静态文件

    一般是由于 Nginx 配置文件的问题 # 编辑 Nginx 配置文件 vim /etc/nginx/nginx.conf # 如果出现下面这个 use nginx 就需要改成 use root 保存 ...

  8. Bitmap优化详谈

    目录介绍 01.如何计算Bitmap占用内存 1.1 如何计算占用内存 1.2 上面方法计算内存对吗 1.3 一个像素占用多大内存 02.Bitmap常见四种颜色格式 2.1 什么是bitmap 2. ...

  9. 记录--uniapp登录流程详解uni.login

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 uni.login(OBJECT)登录 H5平台登陆注意事项: 微信内嵌浏览器运行H5版时,可通过js sdk实现微信登陆,需要引入一个单 ...

  10. 记录--从AI到美颜全流程讲解

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 美颜和短视频 美颜相关APP可以说是现在手机上的必备的软件,例如抖音,快手,拍出的"照骗"和视频不加美颜效果,估计没有 ...