Maybe my brain is just dragging today.
I have a bunch of bytes in the range 0-255 that I need to scale down uniformly by some coefficient. In the absence of floats, how would I do this?
@winduptoy Multiple people have tried to explain binary division to me over the years and it still hasn't sunk in. I've done my best to always do without.
It has to do with shifting the divider left, so 0.8 becomes 8, then doing your operation, then shift-right to cull the decimals. I don't know beyond that.
The scale factor is also going to be a fixpoint in the range 0 to 1, so 0.8 is going to be 0.8*255 = 204.
So, to scale your number by 0.8, all you have to do is to multiply it by 204 and shift the result right by 8 bits: (n*204) >> 8
@winduptoy if you load your byte into a 16bit register and do same for your coefficient. multiply them together and shift that right by 8 bits
result = (thing * coefficient) >> 8
a coefficient of 0 to 256 would be same as 0.0 to 1.0
convert the coefficient to an unsigned short - if it's between 0 and 1, multiply it by 256, take the integer part, and then do 00 SWAP
convert the bytes to unsigned shorts (again, 00 SWAP)
MUL2-iply each of the resulting shorts by the short coefficient, for a short result in the range 0..65025
DROP the low byte of the result (or, if you want to get fancy, shift it right 7 places and add it to the high byte)
not knowing uxn all that well, i'm not going to attempt to actually write source for it, but hopefully this is enough of a leg-up
Let's say 0x86 is your byte to scale, and the scaling factor is ¾. We use units of 1/256 so the scaling short is written as #00c0.
Start with 86 on the stack → 86,
“#00 SWP” → 00 86,
“#00c0”, the scaling factor → 00 86 00 c0,
“MUL2” → 64 80,
“POP” → 64, your result ✅
(You can also see that it rounds down, if anyone needs to round to the nearest integer you can put “#0080 ADD2” between the MUL2 and the POP.)
@alderwick I see that this logic works exactly the same for shorts.
(0x0190 times 0x00c0 = 0x012c00, POP = 0x012c)
(400 times ¾ = 300)
However, that third byte in 0x012c00 presents a problem for Uxn. MUL4 does not exist, so do you have any tips on accomplishing the same thing with shorts without having to summon a demon? I'm imagining the solution looks like a gnarly mess of shifting and popping, and I have no clue how to make the highest bits carry over into something bigger than a short...
@winduptoy the technique I use is to multiply the bytes of the large integers as shorts so that all the overflow is accounted for.
@alderwick 🤩 Unbelievably helpful! I love the learning and sharing on Merveilles, absolutely the best community. Thanks Andy!
Revel in the marvels of the universe. We are a collective of forward-thinking individuals who strive to better ourselves and our surroundings through constant creation. We express ourselves through music, art, games, and writing. We also put great value in play. A warm welcome to any like-minded people who feel these ideals resonate with them.