|
@@ -1,99 +1,120 @@
|
|
|
local numberConverter = {}
|
|
|
local bit = require("bit")
|
|
|
|
|
|
-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(byteA) ..
|
|
|
- string.char(byteB) ..
|
|
|
- string.char(byteC) ..
|
|
|
- string.char(byteD))
|
|
|
-end
|
|
|
|
|
|
-- 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)
|
|
|
-
|
|
|
+ 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
|
|
|
- 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)
|
|
|
+ hext[#hext+1] = string.char(0xFF, 0x80, 0x00, 0x00)
|
|
|
end
|
|
|
-
|
|
|
- return tonumber(string.gsub(table.concat(hext),"(.)",
|
|
|
- function (c) return string.format("%02X%s",string.byte(c),"") end), 16)
|
|
|
+ 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
|
|
|
+ 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
|
|
|
- sign = 1
|
|
|
+ n = 0.0/0.0
|
|
|
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
|
|
|
+ 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
|