[prev in list] [next in list] [prev in thread] [next in thread] 

List:       lua-l
Subject:    Double to byte array and byte array to double conversion in plain Lua.
From:       Jakub Sztandera <k.sztandera () hotmail ! com>
Date:       2015-03-11 11:22:55
Message-ID: DUB122-W156EBAB0D75F90C64FC24AEA190 () phx ! gbl
[Download RAW message or body]

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
 		 	   		  


[Attachment #3 (text/html)]

<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>Hello,<br>couldn't find anything like that in \
internet so I wrote my own.<br>It converts Lua's double from and to byte array.<br>It \
does not handle well special values, like INF, NaN (they get mixed up) but it handles \
all normalized&nbsp; numbers (as far as I know).<br>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). <br><br>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.<br><br>Code is on MIT licence, so do whatever you \
want.<br><pre>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] &gt; 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<br><font style="" face="Arial,sans-serif"><br></font><font style="" \
face="Arial,sans-serif">Available also on </font><font style="" \
face="Arial,sans-serif"><a href="https://gist.github.com/Kubuxu/e5e04c028d8aaeab4be8" \
target="_blank">https://gist.github.com/Kubuxu/e5e04c028d8aaeab4be8</a></font><font \
style="" face="Arial,sans-serif"><br></font><font style="" \
face="Arial,sans-serif">where in case of found errors updates will be \
released.</font><br></pre><hr><font style="" \
face="Garamond"><br></font><blockquote><font style="" face="Times New Roman">Best \
Regards</font><font style="" face="Times New Roman"><br></font><font style="" \
face="Times New Roman">Jakub (Kubuxu) Sztandera</font><br></blockquote> 		 	   		  \
</div></body> </html>



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic