使用位掩码对范围内的十进制数进行编码
Encoding a decimal number within a range using bitmask
我有一个用例,使用 9 位位掩码对 -5.5 到 +5.5 范围内的数字进行编码,然后在其上应用预定义的偏移量。通过在线教程后,我想出了以下使用 Scala 的方法:
所以我首先找到分辨率为:
val res = 5.5/255
然后对于输入值v:
val minValue = -5.5
val bin = if (v >= minValue) (v/res+(255+1)) else 0
val x = if (bin > 510) 511L else bin.toLong
最后:
val MASK = 0x1FF
(x & MASK) << OFFSET)
这种方法够好吗?
我看到的一个问题是您的代码没有预期更改。如果跨度从 -5.5<-->5.5 变为 -5.5<-->6.1 会怎么样?如果某些掩码是 9 位而其他掩码需要 10 位怎么办?
def encode(v:Double, floor:Double, ceiling:Double, bits:Byte) :Long = {
assert(floor < ceiling, "impossible span")
assert(v >= floor && v <= ceiling, s"$v: out of bounds")
val quantum = (ceiling - floor)/math.pow(2,bits)
((v - floor)/quantum).toLong
}
并且您需要检索这些值。
def decode(v:Long, floor:Double, ceiling:Double, bits:Byte) :Double = {
assert(floor < ceiling, "impossible span")
val quantum = (ceiling - floor)/math.pow(2,bits)
v*quantum - ceiling
}
这在测试代码时也有帮助。
decode(encode(-4.487, -5.5, 5.5, 9)
, -5.5, 5.5, 9) //res0: Double = -4.490234375
decode(encode(2.211, -5.5, 5.5, 9)
, -5.5, 5.5, 9) //res1: Double = 2.19140625
我有一个用例,使用 9 位位掩码对 -5.5 到 +5.5 范围内的数字进行编码,然后在其上应用预定义的偏移量。通过在线教程后,我想出了以下使用 Scala 的方法:
所以我首先找到分辨率为:
val res = 5.5/255
然后对于输入值v:
val minValue = -5.5
val bin = if (v >= minValue) (v/res+(255+1)) else 0
val x = if (bin > 510) 511L else bin.toLong
最后:
val MASK = 0x1FF
(x & MASK) << OFFSET)
这种方法够好吗?
我看到的一个问题是您的代码没有预期更改。如果跨度从 -5.5<-->5.5 变为 -5.5<-->6.1 会怎么样?如果某些掩码是 9 位而其他掩码需要 10 位怎么办?
def encode(v:Double, floor:Double, ceiling:Double, bits:Byte) :Long = {
assert(floor < ceiling, "impossible span")
assert(v >= floor && v <= ceiling, s"$v: out of bounds")
val quantum = (ceiling - floor)/math.pow(2,bits)
((v - floor)/quantum).toLong
}
并且您需要检索这些值。
def decode(v:Long, floor:Double, ceiling:Double, bits:Byte) :Double = {
assert(floor < ceiling, "impossible span")
val quantum = (ceiling - floor)/math.pow(2,bits)
v*quantum - ceiling
}
这在测试代码时也有帮助。
decode(encode(-4.487, -5.5, 5.5, 9)
, -5.5, 5.5, 9) //res0: Double = -4.490234375
decode(encode(2.211, -5.5, 5.5, 9)
, -5.5, 5.5, 9) //res1: Double = 2.19140625