java - 如何在给定范围内将 3 位数字“打包”成一个数字?
问题描述
我正在尝试压缩 3 个数字,所有这些数字都在 -5000 万到 +5000 万之间。如何将所有 3 个数字压缩为一个数字,然后从取消压缩单个数字中再次检索 3 个数字。
例如,如果我有:-3000, 122, 103 将变为单个数字,例如“9484010392”
非冷凝 "9484010392" 将返回 [-3000, 122, 103]
数字 9484010392 只是随机选择的,与示例中的数字没有任何关系,只是为了澄清我所说的单个浓缩数字的意思。
等等
PS用Java编写程序:)
解决方案
要将 3 个数字“合并”为一个数字,当 3 个输入(包括符号)较小时,合并值较小,我们可以将数字的位交错,最后放置一个单独的符号位(LSB)。
例如对于输入[-3000, 122, 103]
,位数学是:
-3000 -> sign=1, mag = 3000 = 0b1011_1011_1000 -> 0b1_0111_0111_0001
122 -> sign=0, mag = 122 = 0b111_1010 -> 0b1111_0100
103 -> sign=0, mag = 103 = 0b110_0111 -> 0b1100_1110
要合并它们,我们需要在位之间注入两个 0 位,并将数字中的两位向左移动一位和两位,然后使用按位合并它们OR
。
shift=0, 1011101110001 -> 1000001001001000001001001000000000001
shift=1, 11110100 -> 10010010010000010000000
shift=2, 11001110 -> 100100000000100100100000
OR: 1000001001001110111011011100110100001 = 69958744481
如果将结果存储在 64 位long
中,则每个数字留下 21 位,即 1 个符号位和 20 个幅度位,因此它可以处理高达 ±1048576 的值,即大约 ±100 万。
如果您想要一个高达 ±5000 万的范围,则结果必须存储在BigInteger
.
不知道这是否是您正在寻找的东西,但如果是的话,祝您好运。
推荐阅读
- npm - 为什么 ng(angular-cli) 不被识别为内部或外部命令?
- ruby - Ruby 使用 ipdata API 获取 IP 地址信息
- bash - 为什么“$
" 执行文件名补全? - c# - 按下播放后不同列表中的Unity序列化对象不相等
- ruby-on-rails - Rails 命名空间 has_many 通过缺少的列
- c# - 尝试使用列表反序列化嵌套的 xml
- python - 将大型 csv 快速转换为 geojson
- vba - CommandBars("Text").Controls 退出文档时未删除 - VBA word 插件
- javascript - 格式错误的 utf-8 数据 cryptoJS
- mysql - 为另一个表中的每个元素创建一个包含一列的新表