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. 图像识别算法--VGG16

    前言:人类科技就是不断烧开水(发电).丢石头(航天等).深度学习就是一个不断解方程的过程(参数量格外大的方程) 本文内容: 1.介绍VGG16基本原理 2.VGG16 pytorch复现 图像识别算法 ...

  2. [前端] html和原生js实现鼠标拖动和触摸拖动以及点击后跟随鼠标移动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. C/C++ 的 指针/引用 传参

    #include <stdio.h> //指针传值 void addOne(int *a) { printf("%8p\n",a); *a = *a+1; } //引用 ...

  4. 压测中TPS上不去的几种原因及分析?

    1. 服务器资源限制:服务器的硬件资源(如 CPU.内存.磁盘)可能不足以处理大量的请求.在高负载情况下,服务器可能无法及时响应所有的请求,导致 TPS 上不去.解决方法可以考虑升级硬件资源或通过负载 ...

  5. nginx 基本功能

    1.nginx简介 官方文档 Nginx是一个高性能WEB服务器,除它之外Apache.Tomcat.Jetty.IIS,它们都是Web服务器,或者叫做WWW(World Wide Web)服务器,相 ...

  6. 科技大厂、手机厂商、企服领域齐发力,手机智能体成AI Agent新趋势

    AI Agent涌向移动终端,手机智能体势不可挡 还没搞清楚什么是AI Agent,手机Agent就已经横空出世 AIGC为何涌向移动端?背后有哪些逻辑?什么是手机智能体?一文看明白 科技大厂.手机厂 ...

  7. python Ai 应用开发基础训练,字符串,字典,文件

    --------------------------------------    编程能是大模型应用的天花板............................................. ...

  8. vscode 合并分支 举例 master merge dev

    举例 将 dev 开发线 合并到 master 1 确定你在dev线,将dev代码改动全部提交 2 切换master,确定是最新代码,不确定就pull下,选择合并分支,见上图 3 在下拉的提示框中选择 ...

  9. AOSP-刷机

    准备 1.AOSP源码下载 可以参考AOSP下载且编译 这里我下载的是android-12.1.0_r5的AOSP源码 2.下载驱动 因为我下载的是android-12.1.0_r5的AOSP源码,因 ...

  10. Mysql中数据类型括号中的数字代表的含义

    相信大家不管是看别人的代码,还是自己的代码总会在定义表的数据类型时,会需要在数据类型后面加一个括号,里面写一个参数,例如int(3),smallint(5),char(5)等,但是括号里面的数字到底是 ...