【问题标题】:Bit operations in LuaLua 中的位操作
【发布时间】:2014-08-15 01:52:07
【问题描述】:

我尝试解析 gpx 文件并输出 encoded polylines (Google algorithm)

test.gpx

    <trkseg>
                <trkpt lon="-120.2" lat="38.5"/>
                <trkpt lon="-120.95" lat="40.7"/>
                <trkpt lon="-126.453" lat="43.252"/>
    </trkseg>

我处理了大部分,但在编码数字时遇到了麻烦

gpx2epl:

file = io.open(arg[1], "r")
io.input(file)
--
function round(number, precision)
   return math.floor(number*math.pow(10,precision)+0.5) / math.pow(10,precision)
end

function encodeNumber(number)
  return number
end
--
local Olatitude = 0
local Olongitude = 0
--
while true do
  local line = io.read()
  if line == nil 
  then 
    break 
  end
  if string.match(line, "trkpt") then
    local latitude
    local longitude
    local encnum
    latitude = string.match(line, 'lat="(.-)"')
    longitude = string.match(line, 'lon="(.-)"')
    latitude = round(latitude,5)*100000
    longitude = round(longitude,5)*100000
    encnum = encodeNumber(latitude-Olatitude)
    print(encnum)
    encnum = encodeNumber(longitude-Olongitude)
    print(encnum)
    Olatitude = latitude
    Olongitude = longitude
  end
end

此脚本生成预期的输出(请参阅:Google 链接),但编码的纬度和经度除外。

3850000
-12020000
220000
-75000
255200
-550300

Mapquest 提供了 Javascript 的实现:

function encodeNumber(num) {
   var num = num << 1;
   if (num < 0) {
      num = ~(num);
   }
   var encoded = '';
   while (num >= 0x20) {
      encoded += String.fromCharCode((0x20 | (num & 0x1f)) + 63);
      num >>= 5;
   }
   encoded += String.fromCharCode(num + 63);
   return encoded;   
}

这可以在 Lua 中完成吗?有人可以帮帮我吗。我不知道如何在 Lua 中实现这一点。

编辑:

根据 Doug 的建议,我做了:

function encodeNumber(number)
  local num = number
  num = num * 2
  if num < 0
  then
    num = (num * -1) - 1
  end
  while num >= 32
  do
    local num2 = 32 + (num % 32) + 63
    print(string.char(num2))
    num = num / 32
  end
  print(string.char(num + 63) .. "\n-----")
end

encodeNumber(3850000)   -- _p~iF
encodeNumber(-12020000) -- ~ps|U
encodeNumber(220000)    -- _ulL
encodeNumber(-75000)    -- nnqC
encodeNumber(255200)    -- _mqN
encodeNumber(-550300)   -- vxq`@

它接近预期的输出,但只是接近......有什么提示吗?

【问题讨论】:

  • lua 5.2 包含一个 bit32 库,luajit 也包含位操作,luabitop 存在用于与 lua 5.1 一起使用
  • 您的 6 个数字的预期输出是多少?它们看起来是正确的;您只是在连接字符时遇到问题吗?
  • @DougCurrie 预期的输出在 Goggle 的网站上,我已将它们添加到我在 encodeNumber 调用后面的编辑中!
  • @DougCurrie 似乎是某种舍入问题。输出有时会出错 1。encodeNumber(-75000) 应该产生 nnqC 但会产生 nnqD
  • 我使用下面的函数得到了 nnqC。

标签: lua bit-manipulation


【解决方案1】:

encodeNumber 零碎...

   var num = num << 1;

这只是num = num * 2

   num = ~(num);

这是num = (- num) - 1

   0x20 | (num & 0x1f)

相当于32 + (num % 32)

   num >>= 5

相当于num = math.floor(num / 32)

附录

要连接字符,请使用表格来收集它们:

function encodeNumber(number)
  local num = number
  num = num * 2
  if num < 0
  then
    num = (num * -1) - 1
  end
  local t = {}
  while num >= 32
  do
    local num2 = 32 + (num % 32) + 63
    table.insert(t,string.char(num2))
    num = math.floor(num / 32) -- use floor to keep integer portion only
  end
  table.insert(t,string.char(num + 63))
  return table.concat(t)
end

【讨论】:

  • 我采纳了您的建议来实施encodeNumber,但似乎仍然存在问题。我几乎得到了预期的输出,但几乎没有。查看我的编辑。
  • @Josef - 除法运算可以产生小数结果,所以我只是添加了一个地板运算来保持 num 一个整数。
猜你喜欢
  • 2014-03-09
  • 1970-01-01
  • 2012-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多