Simple 4 Function Floating Point Calculator
jazzed
Posts: 11,803
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.
Here's the "calc.c" source:
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
"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
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.
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
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
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