It is currently Sun Sep 22, 2019 1:40 pm

 All times are UTC - 7 hours

 Page 1 of 1 [ 13 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: Fastest method to convert unsigned int to byte arrayPosted: Tue Nov 20, 2018 2:33 pm

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1904
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

Top

 Posted: Tue Nov 20, 2018 2:49 pm

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11412
Location: Rio de Janeiro - Brazil
Isn't this just the same old binary to decimal problem that was discussed to death recently and so many times in the past?

Top

 Posted: Tue Nov 20, 2018 2:52 pm

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7582
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.

Top

 Posted: Tue Nov 20, 2018 3:00 pm

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1904
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

Top

 Posted: Tue Nov 20, 2018 3:12 pm

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7582
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.

Top

 Posted: Tue Nov 20, 2018 3:13 pm

Joined: Thu Mar 31, 2016 11:15 am
Posts: 529
Top

 Posted: Tue Nov 20, 2018 5:26 pm

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1904

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

Top

 Posted: Tue Nov 20, 2018 5:41 pm

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11412
Location: Rio de Janeiro - Brazil
Not all assemblers require labels to be followed by colons.

Top

 Posted: Wed Nov 21, 2018 1:49 am

Joined: Thu Sep 15, 2016 6:29 am
Posts: 903
Location: Denmark (PAL)
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.

Top

 Posted: Wed Nov 21, 2018 2:43 am

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11412
Location: Rio de Janeiro - Brazil
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.

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.

Top

 Posted: Wed Nov 21, 2018 2:56 am

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1904
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

Top

 Posted: Wed Nov 21, 2018 3:18 am

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7582
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.

Top

 Posted: Wed Nov 21, 2018 8:55 am

Joined: Mon Oct 06, 2014 12:37 am
Posts: 208
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:
*main_init
(code)
*main_loop
(code)

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 13 posts ]

 All times are UTC - 7 hours

#### Who is online

Users browsing this forum: wonder and 6 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum

Search for:
 Jump to:  Select a forum ------------------ NES / Famicom    NESdev    NESemdev    NES Graphics    NES Music    Homebrew Projects       2019 NESdev Competition       2018 NESdev Competition       2017 NESdev Competition       2016 NESdev Competition       2014 NESdev Competition       2011 NESdev Competition    Newbie Help Center    NES Hardware and Flash Equipment       Reproduction    NESdev International       FCdev       NESdev China       NESdev Middle East Other    General Stuff    Membler Industries    Other Retro Dev       SNESdev       GBDev    Test Forum Site Issues    phpBB Issues    Web Issues    nesdevWiki