lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hello,
couldn't find anything like that in internet so I wrote my own.
It converts Lua's double from and to byte array.
It does not handle well special values, like INF, NaN (they get mixed up) but it handles all normalized  numbers (as far as I know).
Used bit order is little-endian but modifying it to big-endian shouldn't be hard (but little-endian is pretty much standard for floating point).

I post this here as I am sure that someone will be some day seeking such tool and archives of this list are the best place I could think of to publish this code.

Code is on MIT licence, so do whatever you want.
function readDouble(bytes) 
  local sign = 1
  local mantissa = bytes[2] % 2^4
  for i = 3, 8 do
    mantissa = mantissa * 256 + bytes[i]
  end
  if bytes[1] > 127 then sign = -1 end
  local exponent = (bytes[1] % 128) * 2^4 + math.floor(bytes[2] / 2^4)
  
  if exponent == 0 then
    return 0
  end
  mantissa = (math.ldexp(mantissa, -52) + 1) * sign
  return math.ldexp(mantissa, exponent - 1023)
end

function writeDouble(num)
  local bytes = {0,0,0,0, 0,0,0,0}
  if num == 0 then
    return bytes
  end
  local anum = math.abs(num)
  
  local mantissa, exponent = math.frexp(anum)
  exponent = exponent - 1
  mantissa = mantissa * 2 - 1
  local sign = num ~= anum and 128 or 0
  exponent = exponent + 1023
  
  bytes[1] = sign + math.floor(exponent / 2^4)
  mantissa = mantissa * 2^4
  local currentmantissa = math.floor(mantissa)
  mantissa = mantissa - currentmantissa
  bytes[2] = (exponent % 2^4) * 2^4 + currentmantissa
  for i= 3, 8 do
    mantissa = mantissa * 2^8
    currentmantissa = math.floor(mantissa)
    mantissa = mantissa - currentmantissa
    bytes[i] = currentmantissa
  end
  return bytes
end

Available also on https://gist.github.com/Kubuxu/e5e04c028d8aaeab4be8
where in case of found errors updates will be released.


Best Regards
Jakub (Kubuxu) Sztandera