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.

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 |

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).

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 |

[Please log in to post a comment]