It is currently Tue Nov 21, 2017 5:02 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: Score add in C
PostPosted: Sat Jul 22, 2017 12:36 pm 
Offline

Joined: Mon Jul 03, 2017 4:37 pm
Posts: 98
This one is putting me in the fetal position, because I am deliberately trying to avoid the division and modulo that is used in the canonical algorithms for converting numbers to an ASCII string, e.g.

Code:
char* itoa(int num, char* str, int base)
{
    int i = 0;
    bool isNegative = false;
 
    /* Handle 0 explicitely, otherwise empty string is printed for 0 */
    if (num == 0)
    {
        str[i++] = '0';
        str[i] = '\0';
        return str;
    }
 
    // In standard itoa(), negative numbers are handled only with
    // base 10. Otherwise numbers are considered unsigned.
    if (num < 0 && base == 10)
    {
        isNegative = true;
        num = -num;
    }
 
    // Process individual digits
    while (num != 0)
    {
        int rem = num % base;
        str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
        num = num/base;
    }
 
    // If number is negative, append '-'
    if (isNegative)
        str[i++] = '-';
 
    str[i] = '\0'; // Append string terminator
 
    // Reverse the string
    reverse(str, i);
 
    return str;
}


Implementing a string to string addition works except when I try to handle the carry, and I've implemented it nine times (yes, I actually am saying this in Ed Rooney's voice), and can't seem to make an algorithm that handles the carry correctly.

I suck atm.

-Thom


Top
 Profile  
 
 Post subject: Re: Score add in C
PostPosted: Sat Jul 22, 2017 6:35 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19237
Location: NE Indiana, USA (NTSC)
Omegamatrix wrote a 16 bits to 5 digits converter that finishes in less than 200 cycles. It's written in assembly language, but if you ask nicely, someone can adapt its calling convention to work when called from C code compiled by cc65.


Top
 Profile  
 
 Post subject: Re: Score add in C
PostPosted: Sat Jul 22, 2017 8:03 pm 
Offline

Joined: Mon Jul 03, 2017 4:37 pm
Posts: 98
tepples wrote:
Omegamatrix wrote a 16 bits to 5 digits converter that finishes in less than 200 cycles. It's written in assembly language, but if you ask nicely, someone can adapt its calling convention to work when called from C code compiled by cc65.


Ah, Omegamatrix is here too. I've known him for over a decade on AtariAge. He hasn't signed on in over a year in either place, it seems...

-Thom


Top
 Profile  
 
 Post subject: Re: Score add in C
PostPosted: Sat Jul 22, 2017 8:16 pm 
Offline
User avatar

Joined: Mon Feb 07, 2011 12:46 pm
Posts: 932
I invented another way (for signed 16-bit numbers into decimal), which however requires many more ROM tables and special pattern tables. I have not compared the speed

However, in some cases you can just work in base 10 or base 100 for scoring anyways and it will work, and you do not need to convert (although you can't use 6502 decimal mode so you have to implement it by yourself instead). (It depends much on the program.)

_________________
.


Top
 Profile  
 
 Post subject: Re: Score add in C
PostPosted: Sat Jul 22, 2017 11:43 pm 
Offline

Joined: Mon Jul 03, 2017 4:37 pm
Posts: 98
zzo38 wrote:
I invented another way (for signed 16-bit numbers into decimal), which however requires many more ROM tables and special pattern tables. I have not compared the speed

However, in some cases you can just work in base 10 or base 100 for scoring anyways and it will work, and you do not need to convert (although you can't use 6502 decimal mode so you have to implement it by yourself instead). (It depends much on the program.)


I wound up doing it like this:

Code:
#include <stdio.h>
#include <math.h>

static unsigned char score0[7]={"0000100"};
static unsigned char score1[7]={"0000000"};

static unsigned char i;
static unsigned char a;

/**
 * Add score0 to score1
 */
void add_points(void)
{
  a=0; // clear carry

  // Convert result to binary.
  for (i=6;i-->0; )
    {
      score0[i]=score0[i]-'0';
      score1[i]=score1[i]-'0';
    }

  // Add each piece
  for (i=6;i-->0; )
    {
      score1[i]=score0[i]+score1[i]+a;
      a=(score1[i]>9);
      if (a)
        score1[i]-=10;
    }

  // Convert result back to ASCII
  for (i=6;i-->0; )
    {
      score0[i]=score0[i]+'0';
      score1[i]=score1[i]+'0';
    }
}

void main(void)
{
  for (int q=0;q<1000;++q)
    {
      add_points();
      printf("%c%c%c%c%c%c%c\n",score1[0],score1[1],score1[2],score1[3],score1[4],score1[5],score1[6]);
    }
}


Although, I am altering the ASCII converts, as my number tiles start a 0x01 now.

-Thom


Top
 Profile  
 
 Post subject: Re: Score add in C
PostPosted: Sun Jul 23, 2017 12:38 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
I spy with my little eye a bug. Your loop should start from i=7 since you decrement in the loop condition. (Which, I have to say, is a very non-standard thing to do, but I think I see why you did it.) Anyway, as it is right now the least significant digit is not handled. I'd also get rid of the binary/ASCII conversions altogether, and simply adjust the comparison in the addition loop. (E.g., if you want to keep using ASCII, generate carry when result > '0'+9.)

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
 Post subject: Re: Score add in C
PostPosted: Sun Jul 23, 2017 3:56 am 
Offline

Joined: Mon Jul 03, 2017 4:37 pm
Posts: 98
Correct on both counts, have fixed this, and will post up in the wiki. :)

-Thom


Top
 Profile  
 
 Post subject: Re: Score add in C
PostPosted: Sun Jul 23, 2017 9:04 am 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6447
Location: UK (temporarily)
Have you looked into storing your 'unpacked BCD' representations little-endian? It would let you add different sizes of numbers easily, rather than requiring everything in 6 bytes.


Top
 Profile  
 
 Post subject: Re: Score add in C
PostPosted: Sun Jul 23, 2017 9:28 am 
Offline

Joined: Mon Jul 03, 2017 4:37 pm
Posts: 98
lidnariq wrote:
Have you looked into storing your 'unpacked BCD' representations little-endian? It would let you add different sizes of numbers easily, rather than requiring everything in 6 bytes.


That's a definite possibility, for now it's on my list of crunching bytes to save space.

-Thom


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group