Fastest method to convert unsigned int to byte array

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
DRW
Posts: 1908
Joined: Sat Sep 07, 2013 2:59 pm

Fastest method to convert unsigned int to byte array

Post by DRW » Tue Nov 20, 2018 2:33 pm

For my new game, I need a way to convert a two-byte unsigned integer value into an array of byte values where each array item represents one decimal digit.

So, if this is my variable:

static uint number = 24680;

then the converted array (byte numberArray[5]) shall have these values:

numberArray[0] == 2
numberArray[1] == 4
numberArray[2] == 6
numberArray[3] == 8
numberArray[4] == 0

If it's faster and easier to calculate, this would also work:

numberArray[0] == 0
numberArray[1] == 8
numberArray[2] == 6
numberArray[3] == 4
numberArray[4] == 2

Which is the fastest way to do this in Assembly? Is there any established best method for it?
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg

User avatar
tokumaru
Posts: 11438
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Fastest method to convert unsigned int to byte array

Post by tokumaru » Tue Nov 20, 2018 2:49 pm

Isn't this just the same old binary to decimal problem that was discussed to death recently and so many times in the past?

User avatar
rainwarrior
Posts: 7636
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Fastest method to convert unsigned int to byte array

Post by rainwarrior » Tue Nov 20, 2018 2:52 pm

If you want to find previous conversations on this topic, this is usually referred to as a conversion to decimal. You might search for "decimal" or for threads about division by 10 / divide by 10 which are almost always the same underlying topic.

The "fastest" way to do this is usually to store the number in decimal form to begin with so you don't have to convert, doing operations on it in decimal as needed.

User avatar
DRW
Posts: 1908
Joined: Sat Sep 07, 2013 2:59 pm

Re: Fastest method to convert unsigned int to byte array

Post by DRW » Tue Nov 20, 2018 3:00 pm

tokumaru wrote:Isn't this just the same old binary to decimal problem that was discussed to death recently and so many times in the past?
Well, that's exactly the thing: There are a bazillion threads with several functions per thread.

So, should people who look for an efficient algorithm search through all those threads, trying out each and every attempt manually?

If this topic has been discussed to death, isn't there a final solution? A definite function that does the conversion in the best way possible?
rainwarrior wrote:The "fastest" way to do this is usually to store the number in decimal form to begin with so you don't have to convert, doing operations on it in decimal as needed.
This might be the fastest way for output. But if you have an energy value that can be decreased by an attack value minus a base defense value minus a temporary status defense value, then is it really the best way to store all these values in five byte long arrays and calculate byte by byte in decimal mode?
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg

User avatar
rainwarrior
Posts: 7636
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Fastest method to convert unsigned int to byte array

Post by rainwarrior » Tue Nov 20, 2018 3:12 pm

DRW wrote:If this topic has been discussed to death, isn't there a final solution? A definite function that does the conversion in the best way possible?
No. Like with most things there are many ways to approach the problem, and every situation has different needs.

Here's a solution tepples put on the wiki though, along with links to a few others:
http://wiki.nesdev.com/w/index.php/16-bit_BCD
DRW wrote:This might be the fastest way for output. But if you have an energy value that can be decreased by an attack value minus a base defense value minus a temporary status defense value, then is it really the best way to store all these values in five byte long arrays and calculate byte by byte in decimal mode?
Sometimes yes, sometimes no. It depends on your specific situation. I can't answer that question for you, you're the one that knows how often you're going to need to convert, but here you asked for the fastest converter rather than the fastest attack calculation.

User avatar
pubby
Posts: 536
Joined: Thu Mar 31, 2016 11:15 am

Re: Fastest method to convert unsigned int to byte array

Post by pubby » Tue Nov 20, 2018 3:13 pm


User avatar
DRW
Posts: 1908
Joined: Sat Sep 07, 2013 2:59 pm

Re: Fastest method to convert unsigned int to byte array

Post by DRW » Tue Nov 20, 2018 5:26 pm

Thanks for your help.

The HexToDec999 code by Omegamatrix is the one that fits my needs best.

This one should really be put into the wiki.
(But it should be cleaned up. For some reason, there are a few compiler errors, like when he forgets to add a : after a label name. I'm not sure how such an error could ever happen.)
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg

User avatar
tokumaru
Posts: 11438
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Fastest method to convert unsigned int to byte array

Post by tokumaru » Tue Nov 20, 2018 5:41 pm

Not all assemblers require labels to be followed by colons.

User avatar
Sumez
Posts: 909
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: Fastest method to convert unsigned int to byte array

Post by Sumez » Wed Nov 21, 2018 1:49 am

rainwarrior wrote: The "fastest" way to do this is usually to store the number in decimal form to begin with so you don't have to convert, doing operations on it in decimal as needed.
Maybe I just suck at ASM programming, but in my experience this is also a shortcut to terrible hard-to-discover bugs in the way you calculate values. The NES CPU really isn't geared for decimal calculations.

If you only ever add/subtract by one you should be fine though.

But I'd absolutely recommend storing your value in a 16 bit space and using tepples 16-bit BCD every time you need to update your visual output.

User avatar
tokumaru
Posts: 11438
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Fastest method to convert unsigned int to byte array

Post by tokumaru » Wed Nov 21, 2018 2:43 am

I personally prefer to keep numbers that are not used in complex calculations in decimal to begin with. Things like scores, number of coins, and other stuff that only goes through simple addition and subtraction.
Sumez wrote:The NES CPU really isn't geared for decimal calculations.
Well, it wasn't designed for running SMB3 either, but people made it do that anyway. :wink:

Doing calculations on decimal digits is exactly the same as working with multi-byte binary numbers, except you have to manually handle the carry and wrapping around. If you write a couple of macros to do it, you don't have to think about this ever again.

User avatar
DRW
Posts: 1908
Joined: Sat Sep 07, 2013 2:59 pm

Re: Fastest method to convert unsigned int to byte array

Post by DRW » Wed Nov 21, 2018 2:56 am

Sumez wrote:But I'd absolutely recommend storing your value in a 16 bit space and using tepples 16-bit BCD every time you need to update your visual output.
tepples' version is slower than the one by Omegamatrix. Especially in situations where your values only need to go to 999. That's the one I'm using now.

Although I had to change it a bit.
For example, he stored the high byte of the integer value in A and the low byte in X.
But passing an integer as a parameter to a function from C, A is the low byte and X the high byte.

Even without C, this is a general inconsistency:

His HexToDec99 and HexToDec255 functions expect their single byte value to be in A.

But HexToDec999 and HexToDec65535 expect the high byte in A and the low byte in X, even though a single byte value is basically the equivalent to the low byte value of an integer, so it's only logical that an integer stored in A and X has the low byte in A and the high byte in X.
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg

User avatar
rainwarrior
Posts: 7636
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Fastest method to convert unsigned int to byte array

Post by rainwarrior » Wed Nov 21, 2018 3:18 am

Sumez wrote:
rainwarrior wrote: The "fastest" way to do this is usually to store the number in decimal form to begin with so you don't have to convert, doing operations on it in decimal as needed.
Maybe I just suck at ASM programming, but in my experience this is also a shortcut to terrible hard-to-discover bugs in the way you calculate values. The NES CPU really isn't geared for decimal calculations.
Well, "fast" and "simple" or "safe" are often in opposition. ;P

Though TBH it doesn't really seem much worse than a regular multi-byte add.

For Lizard I wrote some routines for this (1, 2), but I don't think it's a very good example. I didn't need it to be fast, or even simple, it just needed to work, and it did. :P

User avatar
Alp
Posts: 209
Joined: Mon Oct 06, 2014 12:37 am

Re: Fastest method to convert unsigned int to byte array

Post by Alp » Wed Nov 21, 2018 8:55 am

tokumaru wrote:Not all assemblers require labels to be followed by colons.
Precisely. My own assembler requires labels to be prefixed with an asterisk (*) for example.

Code: Select all

*main_init
(code)
*main_loop
(code)

Post Reply