首页 > 解决方案 > 如何在给定范围内将 3 位数字“打包”成一个数字?

问题描述

我正在尝试压缩 3 个数字,所有这些数字都在 -5000 万到 +5000 万之间。如何将所有 3 个数字压缩为一个数字,然后从取消压缩单个数字中再次检索 3 个数字。

例如,如果我有:-3000, 122, 103 将变为单个数字,例如“9484010392”

非冷凝 "9484010392" 将返回 [-3000, 122, 103]

数字 9484010392 只是随机选择的,与示例中的数字没有任何关系,只是为了澄清我所说的单个浓缩数字的意思。

等等

PS用Java编写程序:)

标签: 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.

不知道这是否是您正在寻找的东西,但如果是的话,祝您好运。


推荐阅读