[Java SE] 经典问题:超出Java Long型(8字节/64位)的二进制比特流数据如何进行大数的数值计算?
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位)的二进制比特流数据如何进行大数的数值计算?的更多相关文章
- 【Java SE】如何用Java实现直接选择排序
摘要:直接选择排序属于选择排序的一种,但是它的排序算法比冒泡排序的速度要快一些,由于它的算法比较简单,所以也比较适合初学者学习掌握. 适宜人群:有一定Java SE基础,明白Java的数据类型,数组的 ...
- 【Java SE】如何用Java实现插入排序
摘要:前面三期分别写了三篇简单排序的算法,今天来讲一点稍微难一点的排序算法-----插入排序. 基本思想: 设n个数据已经按照顺序排列好(假定从小排到大). 输入一个数据x,将其放在恰当的位置,使其顺 ...
- 【Java SE】如何用Java实现反转排序
摘要:反转排序是将原先已经排序好了的重新排序,是原来的数组元素的顺序反转过来.假设原来的数组顺序是{6,5,4,3,2,1},反转之后的顺序就是{1,2,3,4,5,6}.这个排序的算法不是很难,代码 ...
- Java SE 6 新特性: Java DB 和 JDBC 4.0
http://www.ibm.com/developerworks/cn/java/j-lo-jse65/index.html 长久以来,由于大量(甚至几乎所有)的 Java 应用都依赖于数据库,如何 ...
- 【Java SE】如何用Java实现冒泡排序
摘要: 作为一名Java开发工程师,手头如果不会几个常见的排序算法,怎么可能经过笔试题这一关呢.据我所知,许多大型的公司的笔试题都有排序题,那我们先从最简单的排序:冒泡排序开始,以后几篇博客将继续更新 ...
- [零基础学JAVA]Java SE基础部分-01. Java发展及JDK配置
转自:http://redking.blog.51cto.com/27212/114976 重点要会以下两个方面: 1. 抽象类与接口 2. API==>类集 这是两个最重要部分,这两个部分理解 ...
- Java SE基础知识
Java SE面试题 目录 Java SE基础 基本语法 数据类型 关键字 面向对象 集合 集合类概述 Collection接口 List Set Map Java SE基础 基本语法 数据类型 Ja ...
- java SE 入门之八大内置基本类型(第二篇)
本文采用eclipse 工具演示,如果您对eclipse 工具不了解,请先学习下 eclipse 工具的使用,这个里面只是简单的介绍下输出和注释: 安装完成eclipse 以后,双击进入 后一次点击 ...
- Java复习总结(二)Java SE 面试题
Java SE基础知识 目录 Java SE 1. 请你谈谈Java中是如何支持正则表达式操作的? 2. 请你简单描述一下正则表达式及其用途. 3. 请你比较一下Java和JavaSciprt? 4. ...
- Java SE、Java EE、Java ME
Java SE(Java Platform,Standard Edition).Java SE 以前称为 J2SE.它允许开发和部署在桌面.服务器.嵌入式环境和实时环境中使用的 Java 应用程序.J ...
随机推荐
- 手把手教你用 NebulaGraph AI 全家桶跑图算法
前段时间 NebulaGraph 3.5.0 发布,@whitewum 吴老师建议我把前段时间 NebulaGraph 社区里开启的新项目 ng_ai 公开给大家. 所以,就有了这个系列文章,本文是该 ...
- 一文了解 NebulaGraph 上的 Spark 项目
本文首发于 Nebula Graph Community 公众号 最近我试着搭建了方便大家一键试玩的 Nebula Graph 中的 Spark 相关的项目,今天就把它们整理成文分享给大家.而且,我趟 ...
- Linux安装Docker教程
介绍 Docker利用Linux核心中的资源分脱机制,例如cgroups,以及Linux核心名字空间(name space),来创建独立的软件容器(containers).可以在单一Linux实体下运 ...
- 简单封装 Flurl
FlurlHttpClient类 public class FlurlHttpClient { private readonly FlurlClient client; public FlurlHtt ...
- Java 多线程------测试 Thread中的常用方法 + 线程的优先级:
1 package com.bytezero.threadexer; 2 3 import javax.sound.midi.Soundbank; 4 5 /** 6 * 测试 Thread中的常用方 ...
- C++ //常用查找算法 find_if
1 //常用查找算法 find_if 2 #include<iostream> 3 #include<string> 4 #include<vector> 5 #i ...
- HW学习笔记
栈库分离方法注意事项: 所有用户输入数据需要进行分离过滤,不能遗漏.选择安全的过滤函数 如 mysql_real_escape_string(),避免过滤不严格导致注入 SQL查询模板需要设计安全,米 ...
- PDF/Excel文件预览功能完整实现-java版本
新需求 最近接到一个新的需求,说是之前直接下载的PDF文件或者是Excel文件,现在不能直接下载,需要实现在线预览功能. 前端人员拿到这个需求后,去看了一下以前的代码,以前调用的下载接口和PDF文件预 ...
- gyroflow.xyz - 视频防抖 支持相机 gopro 不支持手机视频 - 软件推荐
gyroflow.xyz - 视频防抖 支持相机 gopro 不支持手机视频 - 软件推荐 https://gyroflow.xyz/ https://github.com/gyroflow/gyro ...
- day03-2-应用线程02
JavaGUI-坦克大战03-2 7.线程的应用02 7.3.坦克大战4.0版 坦克大战4.0版 增加功能: 功能1.让敌人的坦克也能够发射子弹(可以有多个子弹) 功能2.当我方坦克集中敌人坦克时,敌 ...