123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- local numberConverter = {}
- local bit = require("bit")
- -- nic'd these from stack overflow
- -- https://stackoverflow.com/a/19996852
- function numberConverter.float2hex(n)
- if n == 0.0 then return 0.0 end
- local sign = 0
- if n < 0.0 then
- sign = 0x80
- n = -n
- end
- local mant, expo = math.frexp(n)
- local hext = {}
- if mant ~= mant then
- hext[#hext+1] = string.char(0xFF, 0x88, 0x00, 0x00)
- elseif mant == math.huge or expo > 0x80 then
- if sign == 0 then
- hext[#hext+1] = string.char(0x7F, 0x80, 0x00, 0x00)
- else
- hext[#hext+1] = string.char(0xFF, 0x80, 0x00, 0x00)
- end
- elseif (mant == 0.0 and expo == 0) or expo < -0x7E then
- hext[#hext+1] = string.char(sign, 0x00, 0x00, 0x00)
- else
- expo = expo + 0x7E
- mant = (mant * 2.0 - 1.0) * math.ldexp(0.5, 24)
- hext[#hext+1] = string.char(sign + math.floor(expo / 0x2),
- (expo % 0x2) * 0x80 + math.floor(mant / 0x10000),
- math.floor(mant / 0x100) % 0x100,
- mant % 0x100)
- end
- return tonumber(string.gsub(table.concat(hext),"(.)",
- function (c) return string.format("%02X%s",string.byte(c),"") end), 16)
- end
- -- nic'd these from stack overflow
- -- https://stackoverflow.com/a/19996852
- function numberConverter.hex2float(c)
- if c == 0 then return 0.0 end
- local c = string.gsub(string.format("%X", c),"(..)",function (x) return string.char(tonumber(x, 16)) end)
- local b1,b2,b3,b4 = string.byte(c, 1, 4)
- local sign = b1 > 0x7F
- local expo = (b1 % 0x80) * 0x2 + math.floor(b2 / 0x80)
- local mant = ((b2 % 0x80) * 0x100 + b3) * 0x100 + b4
- if sign then
- sign = -1
- else
- sign = 1
- end
- local n
- if mant == 0 and expo == 0 then
- n = sign * 0.0
- elseif expo == 0xFF then
- if mant == 0 then
- n = sign * math.huge
- else
- n = 0.0/0.0
- end
- else
- n = sign * math.ldexp(1.0 + mant / 0x800000, expo - 0x7F)
- end
- return n
- end
- function numberConverter.toNetworkFloat(f)
- local n = numberConverter.float2hex(f)
- return numberConverter.toNetworkInt(n)
- end
- function numberConverter.toNetworkInt(originalNumber)
- local byteA = bit.band(originalNumber,0xff)
- local byteB = bit.band(originalNumber,0xff00)
- byteB = bit.rshift(byteB,8)
- local byteC = bit.band(originalNumber,0xff0000)
- byteC = bit.rshift(byteC,16)
- local byteD = bit.band(originalNumber,0xff000000)
- byteD = bit.rshift(byteD,24)
- return (string.char(byteD) ..
- string.char(byteC) ..
- string.char(byteB) ..
- string.char(byteA))
- end
- function numberConverter.toNetworkNumber(originalNumber)
- local n = originalNumber
- if type(originalNumber) == "string" then
- n = tonumber(originalNumber)
- end
- if n == math.floor(n) then
- return numberConverter.toNetworkInt(n)
- else
- return numberConverter.toNetworkFloat(n)
- end
- end
- function numberConverter.intToLuaNumber(netNumString)
- local retval = 0
- local byteD = netNumString:sub(1,1):byte()
- local byteC = netNumString:sub(2,2):byte()
- local byteB = netNumString:sub(3,3):byte()
- local byteA = netNumString:sub(4,4):byte()
- retval = retval + byteA
- retval = retval + bit.lshift(byteB,8)
- retval = retval + bit.lshift(byteC,16)
- retval = retval + bit.lshift(byteD,24)
- return retval
- end
- function numberConverter.floatToLuaNumber(netNumString)
- local hexes = numberConverter.intToLuaNumber(netNumString)
- return numberConverter.hex2float(hexes)
- end
- return numberConverter
|