开发者

Convert byte array to float in Lua [Float Data Structure]

I have the ability to read the memory with Lua, but I've run into a problem. I want to read a float value.

I have, what I presume to be a float, in the 开发者_如何转开发memory which looks like this.

Byte Array 65 B6 40 43 EC 35 87 41 51 04 9E 3F
Float Value 192.712478637695

I know the float value because I'm using a memory editor. In Lua I have a function similar to memcpy, it's called readmem(Address,bytes) it returns an integer value.

How would I read the byte array into a float in Lua using readmem.

For the sake of this question I suppose you could assume that the 6 in 65 is address 00000000.


Weird, this seems to be stored in middle-endian order. (I checked this with http://www.h-schmidt.net/FloatApplet/IEEE754.html)

Anyway, you can do the conversion in pure Lua using code from http://yueliang.luaforge.net/

See also http://lua-users.org/lists/lua-l/2010-03/msg00910.html

If you can use C, try one of the libraries listed in http://lua-users.org/wiki/StructurePacking


This is a fair amount of work to get everything right. You'll need to extract the exponent and significand (the significand is sometimes called the mantissa), convert to float using math.frexp, and then negate the result if the sign bit is set. You'll also have to recognize denormalized numbers and NaNs. (In a normalized number, the most significant bit of the significand is implicit; in a denormalized number it's explicit.) If you simply must do this yourself, you'll find it helpful to read Dave Goldberg's article on everything a computer scientist needs to know about floating point. Also keep in mind that a Lua number is an IEEE double, and be careful about precision.

If I were doing this myself, there's no way I'd go through all this pain—instead I'd write C code to read the bytes and call lua_pushnumber.


string.pack

Passing 'f' as the first parameter will return a 4 byte string of the single precision representation, while 'd' will return an 8 byte string of the double precision representation. You can even declare the endianness of the float


You must write a C function to accomplish the conversion. Lua does not have casts or anything like them.


I cleaned up the answer from @lhf a little:

function BinToFloat32(bin)
  local sig = bin:byte(3) % 0x80 * 0x10000 + bin:byte(2) * 0x100 + bin:byte(1)
  local exp = bin:byte(4) % 0x80 * 2 + math.floor(bin:byte(3) / 0x80) - 0x7F
  if exp == 0x7F then return 0 end
  return math.ldexp(math.ldexp(sig, -23) + 1, exp) * (bin:byte(4) < 0x80 and 1 or -1)
end

I can confirm that this works perfectly for little endian byte input.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜