Shop OBEX P1 Docs P2 Docs Learn Events
Simple 4 Function Floating Point Calculator — Parallax Forums

Simple 4 Function Floating Point Calculator

jazzedjazzed Posts: 11,803
edited 2011-11-13 11:36 in Propeller 1
Here's a simple calculator program. It was simple to write, but harder to use.
The program is a floating point demo. It's better use integer methods on an MCU.

There are other ways to write this calculator in C. Anyone want to try?


Using the floating point library makes the program too big for Propeller LMM by about 6KB.
So, we compile it for XMMC and run it from a 64KB EEPROM or other external memory solution.

Running this program in 64KB EEPROM will require a bug-fix update to the propeller-load program.
The fix will be available soon.
$ propeller-elf-gcc -o calc.elf -mxmmc -Os -Wall calc.c -lm
$ propeller-load -t -r *.elf -b eeprom
Propeller Version 1 on /dev/ttyUSB0
Writing 4552 bytes to Propeller RAM.
Verifying ... Upload OK!
Loading cache driver
1500 bytes sent                  
Loading program image
37496 bytes sent                  
Loading .xmmkernel
1628 bytes sent                  
[ Entering terminal mode. Type ESC or Control-C to exit. ]
5.000000
Very Simple Propeller Calculator Demo
Commands +, -, *, /, or q then number1 number2.
Command? *
Enter first  number: 1.41425
Enter second number: 1.41425
1.414250 * 1.414250 = 2.000103
Command? 

Here's the "calc.c" source:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


const char *cmdchars = "+, -, *, /, or q";


// size of buffer for getting numbers
#define NUMSIZE 12


float getfloat(int num)
{
    static char buff[NUMSIZE];
    printf("Enter %s number: ", (num==1) ? "first ":"second");
    fflush(stdout);
    fgets(buff, NUMSIZE, stdin);
    return atof(buff);          // strtod works too, but it is bigger
}


int main()
{
    char ch = 0;        // assign to supress uninitialized warnings
    float v1 = 2;
    float v2 = 3;


    printf("%f\n", v1+v2);


    printf("Very Simple Propeller Calculator Demo\n");
    printf("Commands %s then number1 number2.", cmdchars);
    for(;;)
    {
        printf("\nCommand? ");
        fflush(stdout);


        /* handle input */
        ch = getchar();
        switch(ch)
        {
            case 'q' :
                return 0;
            case '+' :  // fall through
            case '-' :  // fall through
            case '*' :  // fall through
            case '/' :  // fall through
                getchar();  // clobber newline
                putchar('\b');
                v1 = getfloat(1);
                v2 = getfloat(2);
                break;
            case '\r' : // fall through
            case '\n' : // fall through
                ch = 0; // not a valid command
                break;  // ignore these
            default :
                ch = 0; // not a valid command
                printf("Invalid command. Please enter one of these first: %s\n", cmdchars);
                printf("Then enter 2 numbers for the operation.\n");
                break;
        }


        /* print output */
        if(ch)
        {
            printf("%f %c %f = ",v1,ch,v2);
            switch(ch)
            {
                case '+' :
                    printf("%f",v1+v2);
                    break;
                case '-' :
                    printf("%f",v1-v2);
                    break;
                case '*' :
                    printf("%f",v1*v2);
                    break;
                case '/' :
                    printf("%f",v1/v2);
                    break;
                default :
                    break;
            }
        }
    }
    return 0;
}

Comments

  • Christof Eb.Christof Eb. Posts: 1,237
    edited 2011-11-11 10:38
    Hi jazzed,
    "Using the floating point library makes the program too big for Propeller LMM by about 6KB.
    So, we compile it for XMMC and run it from a 64KB EEPROM or other external memory solution."

    On the one hand I am very impressed by GCC and how it is proceeding - congratulatiuons.

    And integrated floating point for the prop is something, I have been looking for and asked for several times. I think, floating point can help to speed up development time for the cost of lower speed for the application while running. For lower volumes this can make a lot of sense.

    On the other side I am somewhat like really shocked by code sizes. Actually the Prop does not really support external memory and I don't know how many users love the Prop soooo much, that they will give it external memory. And I have used floating point with small ATMEGAs with 16kB. I have seen boards with external memory for the prop but nearly no application for them.

    So -sorry- I do not think, that such code sizes make much sense. I would strongly recommend, to optimise code size, that useful applications can be written without external memory.

    Sorry for this critical feedback, hoping, that you can see it as helpful.
    Christof
  • jazzedjazzed Posts: 11,803
    edited 2011-11-11 11:33
    Thanks Christof.

    I believe this feedback is useful. This is one reason why we are running an Alpha program.

    Your intent seems to be in helping us move in a positive direction, and I certainly respect that.

    I do not have any solid answers at this point for Propeller and I won't speculate much. I will however point out that atMegas are 8 bit processors which generally have better code density. If I recall correctly (someone correct me?) the AVR-GCC library also uses 32bit floating point for floats and doubles.

    I was very surprised that selecting 32 bit floating point over 64 bit floating point with the -m32bit-doubles compiler flag resulted in bigger code (64 bit is the default). I can only assume that maybe, just maybe there is a bug there somewhere.

    I'm hoping Eric or other team members may have more input on this topic soon.

    I agree that Propeller should be useful without external memory. It is after all intended for micro-controller applications.
  • ersmithersmith Posts: 6,100
    edited 2011-11-11 12:00
    jazzed wrote: »
    I was very surprised that selecting 32 bit floating point over 64 bit floating point with the -m32bit-doubles compiler flag resulted in bigger code (64 bit is the default). I can only assume that maybe, just maybe there is a bug there somewhere.
    We don't presently have separate versions of the math library for 32 bit and 64 bit doubles, so only the 64 bit double will be linked. That means that compiling with -m32bit-doubles and -lm causes both 32 bit and 64 bit floating point code to be pulled in, which is why it is bigger.

    It's something we should look at -- it's worth opening on issue on google code. I don't know what priority the floating point library has.

    There is also a slower but smaller floating point library available that we can build in gcc instead of the one we're using.

    Eric
  • jazzedjazzed Posts: 11,803
    edited 2011-11-11 14:46
    Eric, a slower but smaller 32 bit solution seems to be a fine option to me considering the alternatives.

    I'll talk with Parallax staff and get their opinion on this. We can weigh this on Monday. Today is a US holiday. I'm not convinced that having 64 bit floating point on an MCU is so important, but if users want it Propeller GCC provides it now.

    Justifications for floating point on an MCU other than "I want it" would go a long way in factoring whether a smaller 32 bit library will be added.

    This is an Alpha issue and I'll put it on propgcc/issues for tracking until we have a decision one way or another.

    Thanks,
    --Steve

    ersmith wrote: »
    We don't presently have separate versions of the math library for 32 bit and 64 bit doubles, so only the 64 bit double will be linked. That means that compiling with -m32bit-doubles and -lm causes both 32 bit and 64 bit floating point code to be pulled in, which is why it is bigger.

    It's something we should look at -- it's worth opening on issue on google code. I don't know what priority the floating point library has.

    There is also a slower but smaller floating point library available that we can build in gcc instead of the one we're using.

    Eric
  • jazzedjazzed Posts: 11,803
    edited 2011-11-13 11:36
    Christof and everyone,

    Eric has pushed a 32 bit alternative to our repository. The consensus was that it's just the right thing to do.

    With no optimization and specifying using the non-default 32bit-doubles with the standard printf and other ANSI-C standard libraries, the calculator demo compiles to about 28KB, loads, and works just fine. With -Os optimization it is about 1KB smaller. 27KB is still big, but it fits comfortably in Propeller memory for LMM C programs with options as described.

    Of course only 1 COG is used for the entire LMM program. 2 COGs are used for XMM code programs with the cache.

    This will be supported in an upcoming MinGW based Propeller-GCC release. Most of the work has already been done for the release.

    Thanks,
    --Steve
Sign In or Register to comment.