One of the good bits about writing your own calculator is, once it has reached the actually working stage, it's fairly easy to add stuff. I'm planning to add stuff that i find useful. On another calculator, this would have to be a program.
You are right about the display formatting. the C/C++ language does not have a lot of fine control over display of numbers. I have another such problem with matrices. Currently, Reckon formats each number as 6 figures when inside a matrix in the vague hope that it will fit on the screen - mostly not. To do this properly really requires a matrix "viewer" which can scroll. Also how do you peek at one entry to full precision. These things are significant work if done properly.
For complex number display, what i did on the uWatch (www.calcwatch.com) which has a 16 character screen is convert the real part and iparts to strings, then build the display string and see if it is too big. If so, i reduce the ipart a bit otherwise i reduce the real part a bit and try again. Furthermore, i try to trim away any unecessary chars in the numbers (leading zeros etc.). The whole thing is messy, but i was happy that it managed to get the most on the screen most of the time.
code snippets:
// tidy as many unnecessary chars as possible from a sci number
static void tidyNumber(char* p)
{
if (*p == '-') ++p; // skip sign
if (*p == '0' && p[1] == '.')
{
// 0.xxx
strcpy(p, p+1);
}
p = strchr(p, 'e'); // exponent?
if (p)
{
++p;
if (*p == '+')
strcpy(p, p+1);
if (*p == '-') ++p; // '-' allowed
if (*p == '0') // leading zero in exponent
strcpy(p, p+1);
}
}
void FormatValue(char* dest,
double value, double ivalue,
int space, BOOL tidy)
{
....
if (ivalue == 0)
{
// fit into `space's on screen
int p = space-1;
int l;
if (value < 0) --p; // adjust for sign
for (;;)
{
sprintf(dest,"%.*g", p, value);
l = strlen(dest);
if (l <= space)
break;
if (tidy)
{
// try tidying
tidyNumber(dest);
if (strlen(dest) <= space)
break;
}
p -= (l - space);
if (p <= 0) break; // fail safe
}
}
else
{
int l;
char c = '+';
int id = 6;
int d = 7; // cooked guesses at rp, ip sizes
if (ivalue < 0)
{
ivalue = -ivalue;
c = '-';
}
again:
// textify the real part
sprintf(dest,"%.*g", d, value);
// tidy to save precious chars
tidyNumber(dest);
l = strlen(dest);
dest[l++] = c;
dest[l++] = 'i';
dest[l] = 0;
if (ivalue != 1)
{
int li;
// now fit as much of the ipart as we can
for (;;)
{
sprintf(dest + l,"%.*g", id, ivalue);
tidyNumber(dest+l);
li = strlen(dest);
if (li <= space) break; // done
id -= (li - space);
if (id <= 0)
{
// very rarely we cant fit ANY of the ipart
// on display. shorten the real part and
// try again.
d -= 2;
id = d-1;
if (d > 2) goto again;
}
}
}
}
// ensure we dont overrun whatever.
dest[space] = 0;
...
}