Post subject: Lua implementation to read a Q fixed point number for DS
Editor, Experienced player (848)
Joined: 5/2/2015
Posts: 696
Location: France
The DS uses fixed-point numbers for floats with the Q number format, with the sign value stored in m. DeSmuME supports reading and writing to these, but there are two issues: - 0.9.9 only allows for Q20.12 formatted numbers, and not for other values of m or n. - Looking at the DeSmuME lua documentation, there is no function to read these floats, which is sure inconvenient for making a script. Either I hacked in something and backported it to 0.9.9, or used something on the lua side. I chose the latter, but nobody had written something for this, so I wrote it myself: here is the code I used (sorry, it's a bit messy.) Assumes Lua 5.1. Download qlib.lua
Language: lua

-- Simple binary packing function -- To unpack, tonumber(num, 2) function toBits(num,bits) -- returns a table of bits, most significant first. bits = bits or math.max(1, select(2, math.frexp(num))) local t = {} -- will contain the bits for b = bits, 1, -1 do t[b] = math.fmod(num, 2) num = math.floor((num - t[b]) / 2) end return table.concat(t) end -- https://en.wikipedia.org/wiki/Q_(number_format)#Characteristics -- Here, the sign bit is included in m, because n+m = 32, which is equal to -- the length of the DS adress bus -- Unpacking function local function Q(number, m, n) local max = m+n local packed = toBits(number, 32) local sign = tonumber(string.sub(packed, 1, 1)) -- If the number is signed: NOT the number, add 1 (one's complement) if sign == 1 then packed = toBits(bit.bnot(tonumber(packed,2))+1,32) end local integer = tonumber(string.sub(packed, 2, m),2) -- As usual, Lua indexes start at 1.. local fractional = (tonumber(string.sub(packed, m+1, max), 2))/(2^n) local total = integer + fractional if sign == 1 then total = total * -1 end return total end