Log In  

Hi,

The other thread about converting numbers to hex strings got me wondering if it was possible to do the same with fixed point data. (I did try searching here first but didn't find anything about this specifically)

I wrote a quick test to dump the bits out, but for floats I'm not sure where to find the fractional part. I figured it'd be in the top byte, but as the last test shows, it's not there (or my code is wrong). Is it possible to get at this data?

Thanks

function convert(value)
  local binary = ""
  for i=1,16 do
    local shift = shl(1,i-1)
    binary=abs(shr(band(shift,value),i-1))..binary
  end
  print("convert "..value.." to binary:")
  print(binary)

  local integerval = 0
  for k=1,16 do
    local str = shl(sub(binary, k, k),16-k)
    integerval += str
  end
  print("and back again: "..integerval)
  print("")
end

function _init()
  cls()
  convert(0xc0de)
  convert(12345)
  convert(3.14159)
end

Here's a screenshot: (ironically it's larger than the cart, but it's done now)

edit: in fact, the code to convert back is wrong, as it doesn't handle the decimal point. I think the binary conversion is correct though.

P#23458 2016-06-22 21:08 ( Edited 2016-06-23 02:27)

Semi on-topic, I noticed something weird with bitshifts in Lua ... if I took a number and shifted it right, it was equivalent to dividing by 2 (as expected). However, it will go into fractions, rather than forcing an integer value (as it does in say, C#).

[s]Not sure how Lua/Pico-8's bit data looks for representing fractional numbers, but it might use the IEEE-754 format for floating points: https://en.wikipedia.org/wiki/IEEE_754-1985[/s]

I have a function that I use that converts a number to a string to 2 decimal places (it actually works for 1-4 places):

-- converts a number to string
function format(n,d)
  return
    flr(n) .. "." ..
    flr(n%1 * 10^d)
end
P#23460 2016-06-22 21:31 ( Edited 2016-06-23 02:28)
2

PICO-8's numbers are simply signed 16.16 values. That means the upper 16 bits represent whole numbers and the lower 16 represent the fraction. Under the hood, it's nothing more than a signed 32-bit integer that holds the lua value multiplied by 65536.

As such, shifting right doesn't eliminate bits until they are 16 bits below the decimal point, or at bit 0 in the underlying integer. So yes, it's intended that SHR(1) == 0.5. What's really happening under the hood is that you're shifting integer 65536 (representing 1.0 in Lua) right by one to become 32768 (representing 0.5).

P#23465 2016-06-22 22:06 ( Edited 2016-06-23 02:06)
2

This is how I'd adapt your code to include the fractional bits.

function convert(value)
   local binary = ""
   print("convert "..value.." to binary:")
   for i=1,32 do
      binary=band(shl(value,16),1)..binary
      value=shr(value,1)
   end
   print(binary)

   local integerval = 0
   for k=1,32 do
     integerval=shl(integerval,1)+shr(sub(binary, k, k), 16)
   end
   print("and back again: "..integerval)
   print("")
 end

 function _init()
   cls()
   convert(0xc0de)
   convert(12345)
   convert(3.14159)
 end
P#23470 2016-06-22 22:27 ( Edited 2016-06-23 02:50)

Fix: Just updated it because I realized I'd written (and read!) the bits in backwards order. :)

P#23473 2016-06-22 22:33 ( Edited 2016-06-23 02:33)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-28 15:10:53 | 0.007s | Q:15