Shop OBEX P1 Docs P2 Docs Learn Events
Floating Point Programmable Scientific Calculator. — Parallax Forums

Floating Point Programmable Scientific Calculator.

Duane C. JohnsonDuane C. Johnson Posts: 955
edited 2012-11-05 15:26 in Propeller 1
Hi All;

If there an application that is essentially a "Floating Point Programmable Scientific Calculator".
I didn't see one in the OBEX.

So here is the challenge. Write a reasonable Scientific Calculator. It should be able to have these features:
1. Ideally it should be a replica of an HP15C but other calculators may be acceptable models.
2. The number system should internally use 64 bit binary IEEE 754.
3. The input and output should be, like the calculators, in decimal, scientific, or engineering notation as well as the IEEE 754.
4. Programming should work similar to forth, with stacks, but with floating point numbers, just as in the HP15C.
5. In general, I see the human interface as a terminal. But I suppose an LCD and keyboard would also work.

Most programming languages can use 32 bit integers because the applications are restricted but run fast.
Speed is much less important for scientific applications. I see this more for as a calculator.
However, unlike my HP15C I could have measurement inputs and driver outputs.

Does this sound doable?
I'm not a programmer so I don't think I can do this in any reasonable way.
I'm more of an "Appliance User" of GWBasic, FemtoBasic, Forth, and Spreadsheets.
This could be a very useful application.

What do you say guys?

Duane J

Comments

  • User NameUser Name Posts: 1,451
    edited 2012-11-02 19:57
    gcc certainly seems to be the choice for calculations since double-precision floating point is already there, as is formatted printing to strings. The kbd, serial, and display objects already exist in Spin/PASM. Seems like a stack-based calculator (meaning RPN) would be pretty simple to pull off. Is the 15C RPN? If not, the project loses much of its interest and/or utility.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-11-02 20:16
    I'd love to see something like this. I'm not aware of any easy to use 64-bit math objects to use with the Propeller.

    Codeviper wrote a 32-bit floating point calculator program. It uses a slightly modified version of F32 (IIRC it was modified to make it easier to use from multiple objects).

    It uses a TV for output and a keyboard for input. It shouldn't be hard to modify to use a terminal program instead of TV and keyboard.
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-11-02 20:26
    Hi User Name;
    User Name wrote: »
    gcc certainly seems to be the choice for calculations since double-precision floating point is already there, as is formatted printing to strings. The kbd, serial, and display objects already exist in Spin/PASM. Seems like a stack-based calculator (meaning RPN) would be pretty simple to pull off. Is the 15C RPN? If not, the project loses much of its interest and/or utility.
    Oh yes, The HP15C and many other HP calculators are all RPN. I have had many over the years.

    See others at the HP Calculator Museum.

    I only mention the HP15C as its my current favorite.
    This calculator has a very limited program storage and was strictly hand loaded. But I really liked how it operated. The HP41 and HP48 are other good models. I really didn't like the HP28 though.

    Duane J
  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-02 22:39
    Hi All;

    If there an application that is essentially a "Floating Point Programmable Scientific Calculator".
    I didn't see one in the OBEX.

    So here is the challenge. Write a reasonable Scientific Calculator. It should be able to have these features:
    1. Ideally it should be a replica of an HP15C but other calculators may be acceptable models.
    2. The number system should internally use 64 bit binary IEEE 754.
    3. The input and output should be, like the calculators, in decimal, scientific, or engineering notation as well as the IEEE 754.
    4. Programming should work similar to forth, with stacks, but with floating point numbers, just as in the HP15C.
    5. In general, I see the human interface as a terminal. But I suppose an LCD and keyboard would also work.

    Most programming languages can use 32 bit integers because the applications are restricted but run fast.
    Speed is much less important for scientific applications. I see this more for as a calculator.
    However, unlike my HP15C I could have measurement inputs and driver outputs.

    Does this sound doable?
    I'm not a programmer so I don't think I can do this in any reasonable way.
    I'm more of an "Appliance User" of GWBasic, FemtoBasic, Forth, and Spreadsheets.
    This could be a very useful application.

    What do you say guys?

    Duane J
    I wrote a demo program for Propeller GCC that evaluates numeric infix expressions and prints their values. It also allows you to assign variables that can be used in subsequent calculations. I built it with single precision floating point but there is no reason it can't be built with double precision. I'll attach it to this message.
    c
    c
    18K
    h
    h
    2K
  • jazzedjazzed Posts: 11,803
    edited 2012-11-02 22:50
    David's program also offers sin, cos, tan, asin, acos, atan, ln, exp, and sqrt in addition to the typical 4 functions in 32bit float with CMM and room to grow. In my experience 64bit math with all those functions is tight and will fail at run time - some features need to be pruned to make room for 64 bit.
  • jmgjmg Posts: 15,173
    edited 2012-11-03 01:16
    3. The input and output should be, like the calculators, in decimal, scientific, or engineering notation as well as the IEEE 754.

    No Decimal or Hex or Binary ?
    4. Programming should work similar to forth, with stacks, but with floating point numbers, just as in the HP15C.
    5. In general, I see the human interface as a terminal. But I suppose an LCD and keyboard would also work.

    RPN and stacks was ok for numeric-only, limited char displays, but shouldn't a Prop Calc with a Keyboard (either direct, or terminal)
    allow a more line-editor approach ? - it will nearly always have a multiple line display ?

    This PC one CCalc (100 digits) has a line editor & supports multiple eqns, semi colon delimited.

    http://www.zoesoft.com/blog/
  • RaymanRayman Posts: 14,670
    edited 2012-11-03 07:15
    My favorite is RayRPN:
    http://www.rayslogic.com/Software/Rays_RPN/RayRPN.htm

    should be easy enough to port with GCC or Catalina...
  • jmgjmg Posts: 15,173
    edited 2012-11-03 14:36
    Rayman wrote: »

    Nicely presented. A little light on displayed digits for my liking. What is the internal precision ?
  • RaymanRayman Posts: 14,670
    edited 2012-11-03 18:09
    it's been a while, but I think it was plain double precision. Gives the same answer as my HP15c in every test...
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-11-03 18:35
    Check out Dave Hein's pfth thread. Floating point could probably be added and then you'd have your calculator and forth too!
  • frank freedmanfrank freedman Posts: 1,983
    edited 2012-11-03 18:49
    Maybe you could adapt the hp48 emu to the prop. Is it faster than the saturn chip? Have any of the emulators tried to create a single or multi cog emulation of the saturn chip? You have C, all you may need is a good cog based cordic. Would love to do this, but don't understand it well enough to do it.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-11-03 19:23
    If it is possible to do this in Spin then maybe we can add some scientific functions to the touchscreen calculator? A new skin could be designed if it needs more buttons (this one has 3 buttons free).
    CON
      _clkmode      = xtal1 + pll16x                        ' use crystal x 16
      _xinfreq      = 5_000_000
       
    OBJ
      tch:           "Touch"                                 ' touchscreen driver
    
    PUB Main | touchtest  ' debug value
      tch.BeginProgram
      Calculator
      tch.SetWarmBoot                                           ' clears screen, sets a warm boot and reboots
    
    PUB Calculator | xval,yval,address,ascii,operand,font,a,b,answer
        tch.Clearscreen(%00000000_00000000)                 ' so something happens immediately
        tch.ClearRam
        tch.SDBMPtoRam(string("calcpic.bmp"))                ' file 2
        tch.DrawBMPRam(2,0,0)                               ' draw the picture    
        font := tch.Loadfont(string("DSdig.ifn"))           ' file 3 in the ram disk, use this number when printing fonts
        tch.stringdim(10)                                   ' file 4is strings group, create some string space
        tch.stringclear(0)                                  ' use string 0
        tch.SelectSPIGroup                                   ' talk to the spi touchscreen  
        repeat
          yval := tch.TouchYPercent                           ' decode yval 0-100%               
          xval := tch.TouchXPercent                           ' decode xval 0-100%
          if (xval <> 255)  and (yval <> 255)                    ' valid keypress
            tch.SelectMemGroup                              ' disconnect spi and talk to display
            'tch.hex(xval,2)                                 ' debugging
            address :=1 ' button doesn't do anything = default
            case (yval*32)/10                                    ' convert 0-100 to 0-320 as easier to work with pixels off the picture
              60..101: address :=0                               ' row of a 4x6 matrix
              104..140: address :=4
              146..183: address :=8
              187..222: address :=12
              228..265: address :=16
              271..307: address :=20
            case (xval*24)/10                                   ' column convert percent to 0-239
              0..66: address += 0
              67..119: address +=1
              120..172: address +=2
              173..239: address +=3
            ascii := lookupz(address: "X","Q","Q","Q","C",8,"/","*","7","8","9","-","4","5","6","+","1","2","3","=","0","0",".","=")
            case ascii
              "X"             : return                                              ' close the calculator
              "C"             : tch.stringclear(0)                                  ' clear the current string
                                CalcClear
              "0".."9"        : tch.StringAddChar(0,ascii) ' build the string
                                CalcClear
                                tch.StringPrint(font,0)                             ' print string
              "+","-","*","/" : tch.StringCopy(1,0)                                 ' copy string 0 to string 1 
                                tch.StringAddChar(0,ascii) ' display these too so can see typed something
                                CalcClear
                                tch.StringPrint(font,0)                             ' print string
                                tch.StringClear(0)                                  ' clear working string
                                operand := ascii
              "=" :             a := tch.StringVal(1)                               ' second value
                                b := tch.StringVal(0)                               ' first value
                                case operand
                                      "+" : answer := a + b                         ' add
                                      "-" : answer := a - b                         ' subtract
                                      "*" : answer := a * b                         ' multiply
                                      "/" : answer := a / b                         ' integer division
                                tch.StringStr(2,answer)                             ' store answer to string 2
                                CalcClear                                            ' clear the display ready to print the answer
                                tch.StringPrint(font,2)                             ' print the answer
            tch.SelectSPIGroup                                              ' restart the spi group if display something
            tch.pause1ms(250)' only display once so delay half a second to "debounce"
    
    PUB CalcClear
         tch.ClearRectangle(25,21,220,48,tch.GetBackFontColor) ' clear an area the same color as the font background   
         tch.SetCursor(25,15)
    
    800 x 600 - 78K
  • ersmithersmith Posts: 6,054
    edited 2012-11-04 08:53
    jazzed wrote: »
    David's program also offers sin, cos, tan, asin, acos, atan, ln, exp, and sqrt in addition to the typical 4 functions in 32bit float with CMM and room to grow. In my experience 64bit math with all those functions is tight and will fail at run time - some features need to be pruned to make room for 64 bit.

    In the latest PropGCC (still not released, but the adventurous can build it from source from the "performance" branch) the floating point code is much smaller and more efficient, and David's calculator will fit in CMM mode even with 64 bit doubles: I tried it and it seems to work fine. There's not a lot of space left for other drivers (screen, touchpad, etc.), though perhaps some could be stored in EEPROM.

    Eric
  • localrogerlocalroger Posts: 3,451
    edited 2012-11-04 10:36
    jmg wrote: »
    RPN and stacks was ok for numeric-only, limited char displays, but shouldn't a Prop Calc with a Keyboard (either direct, or terminal)
    allow a more line-editor approach ? - it will nearly always have a multiple line display ?

    You need the line editor because it's hard to keep algebraic notation straight. Once you know how to properly use RPN it's much easier than algebraic, and you don't need a line editor because at any given time you're looking at an intermediate result on the display, not a middle of edit cursor.
  • jmgjmg Posts: 15,173
    edited 2012-11-04 11:37
    ersmith wrote: »
    In the latest PropGCC (still not released, but the adventurous can build it from source from the "performance" branch) the floating point code is much smaller and more efficient, and David's calculator will fit in CMM mode even with 64 bit doubles: I tried it and it seems to work fine. There's not a lot of space left for other drivers (screen, touchpad, etc.), though perhaps some could be stored in EEPROM.

    Do you have a quick resource summary of that ?
    Main RAM usage, how many COGS and what was in each COG ?

    This would make a great education/benchmark for Prop I and Prop II
  • ersmithersmith Posts: 6,054
    edited 2012-11-04 14:22
    jmg wrote: »
    Do you have a quick resource summary of that ?
    Main RAM usage, how many COGS and what was in each COG ?

    David's expr program, compiled in CMM mode with the performance branch PropGCC and 64 bit doubles, takes 31424 bytes of HUB RAM. Only one COG is used, (the main one) so there's lots of room for drivers there, which is why I suggested that storing some drivers in EEPROM might work well.

    64 bit doubles give 15 decimal digits of precision (very nearly 16, actually); 32 bit doubles give 7 digits, so if that's enough precision then it's probably worth dropping down to 32 bit "doubles". The saving is pretty significant, both in code and data. The expr program takes only 25900 bytes of HUB RAM using 32 bit doubles.

    Eric
  • jmgjmg Posts: 15,173
    edited 2012-11-04 15:48
    ersmith wrote: »
    David's expr program, compiled in CMM mode with the performance branch PropGCC and 64 bit doubles, takes 31424 bytes of HUB RAM. Only one COG is used, (the main one) so there's lots of room for drivers there, which is why I suggested that storing some drivers in EEPROM might work well.

    64 bit doubles give 15 decimal digits of precision (very nearly 16, actually); 32 bit doubles give 7 digits, so if that's enough precision then it's probably worth dropping down to 32 bit "doubles". The saving is pretty significant, both in code and data. The expr program takes only 25900 bytes of HUB RAM using 32 bit doubles.

    Eric

    Sounding impressive. 64 bits is the clear winner, given it fits, and this is a great test & bench vehicle for 64 bit libraries & CMM.
    With many COGs spare, could some be used for GCC->PASM blocks, as co-processors ?

    A Calc does not need cutting edge video, so it would be a good place to see what GCC-Display could look like
    (ie code written (mainly) in GCC, compiled to target PASM in COG & Keyboard IO )
  • User NameUser Name Posts: 1,451
    edited 2012-11-04 16:16
    Rayman wrote: »
    My favorite is RayRPN

    Too cool! I've been using XCALC for years. It's a great tool, but yours is so cute!
  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-04 18:28
    jmg wrote: »
    Do you have a quick resource summary of that ?
    Main RAM usage, how many COGS and what was in each COG ?

    This would make a great education/benchmark for Prop I and Prop II
    This is a simple C program that would run on any platform that supports ANSI C. It only uses one COG and maybe a second for a cache driver if compiled to use external memory. Beyond that, the remaining COGs are available to run drivers. It currently just uses the serial port but could easily use TV and PS2 keyboard drivers if there is enough memory for them. As Eric said, those drivers could be loaded from EEPROM if necessary assuming the target board has at least a 64k EEPROM.
  • RossHRossH Posts: 5,463
    edited 2012-11-05 03:12
    ersmith wrote: »
    David's expr program, compiled in CMM mode with the performance branch PropGCC and 64 bit doubles, takes 31424 bytes of HUB RAM. Only one COG is used, (the main one) so there's lots of room for drivers there, which is why I suggested that storing some drivers in EEPROM might work well.

    64 bit doubles give 15 decimal digits of precision (very nearly 16, actually); 32 bit doubles give 7 digits, so if that's enough precision then it's probably worth dropping down to 32 bit "doubles". The saving is pretty significant, both in code and data. The expr program takes only 25900 bytes of HUB RAM using 32 bit doubles.

    Eric

    Just out of interest, I compiled Dave's expr program with Catalina. The only thing I had to do was substitute strcmp for strcasecmp (strcasecmp is not an ANSI function). You can do this on the command line. When compiled with CMM and 32bit floats, the total program size is about 16K of HUB RAM (code size ~14Kb, and data size ~2Kb).

    The commands I used (for the C3) were:
    catalina expr.c -lc -lmb -C C3 -C COMPACT -C TTY -D MAIN -D strcasecmp=strcmp
    payload expr -i
    

    Of course, Catalina saves some space by using the Parallax Float32 OBEX component. There is no equivalent for 64 bit floats, but I've found a 64 bit floating point implementation in ANSI C that looks quite interesting. I may include it in a subsequent release of Catalina. Using that, the program size would go up to about 20kb.

    Ross.
  • RossHRossH Posts: 5,463
    edited 2012-11-05 03:37
    David Betz wrote: »
    This is a simple C program that would run on any platform that supports ANSI C. It only uses one COG and maybe a second for a cache driver if compiled to use external memory. Beyond that, the remaining COGs are available to run drivers. It currently just uses the serial port but could easily use TV and PS2 keyboard drivers if there is enough memory for them. As Eric said, those drivers could be loaded from EEPROM if necessary assuming the target board has at least a 64k EEPROM.

    Ah! Should have read the whole thread before posting - yes, David is quite right. For instance, if you have a 64Kb EEPROM and compile the program to use the Catalina EEPROM loader, you can use any of the available Catalina HMI options (e.g. TV or VGA, HiRes or LoRes).

    For instance, to use HiRes VGA only requires a slight modification to the commands I gave previously. Again, this is for the C3:
    catalina expr.c -lc -lmb -C C3 -C COMPACT -D MAIN -D strcasecmp=strcmp -C HIRES_VGA -C EEPROM
    payload EEPROM expr
    
    One of the nice things about Catalina is that the Hub RAM used by the application remains the same no matter what plugins you use - so this version still has a code size of about 14k and data size of 2k. Of course, the VGA buffers will now take another chunk of Hub RAM (about 6k for HiRes) but you would still have another 8k or so left for more code - more if you used LoRes VGA or TV HMI options instead.

    Ross.
  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-05 04:06
    RossH wrote: »
    Just out of interest, I compiled Dave's expr program with Catalina. The only thing I had to do was substitute strcmp for strcasecmp (strcasecmp is not an ANSI function).
    It is certainly true that strcasecmp is not an ANSI function (and that it has an unfortunate name). It is, however, very useful and is supported in many ANSI-superset libraries and is also known by the name stricmp in some libraries. A minor problem with just replacing it with strcmp is that your "calculator" is now case sensitive.
    When compiled with CMM and 32bit floats, the total program size is about 16K of HUB RAM (code size ~14Kb, and data size ~2Kb).
    That's quite good! I think PropGCC has an option to use that floating point object as well or did at one time.
  • RossHRossH Posts: 5,463
    edited 2012-11-05 04:14
    David Betz wrote: »
    It is certainly true that strcasecmp is not an ANSI function (and that it has an unfortunate name). It is, however, very useful and is supported in many ANSI-superset libraries and is also known by the name stricmp in some libraries. A minor problem with just replacing it with strcmp is that your "calculator" is now case sensitive.
    No problem - I just downloaded strcasecmp.c from here and it works fine. Just modify the Catalina command to:
    catalina expr.c strcasecmp.c -lc -lmb -C C3 -C COMPACT -D MAIN -C HIRES_VGA -C EEPROM
    

    Makes almost no difference to the code size.
    David Betz wrote: »
    That's quite good! I think PropGCC has an option to use that floating point object as well or did at one time.
    Yes, I keep hoping someone will write a 64 bit equivalent - it would save me a chunk of work!

    Ross.
  • ersmithersmith Posts: 6,054
    edited 2012-11-05 05:07
    David Betz wrote:
    I think PropGCC has an option to use that floating point object as well or did at one time.
    Not quite, although it's not too hard to put a wrapper around it. One downside is that Float32 (and its derivatives) do not comply with the IEEE floating point standard -- the rounding is subtly wrong, and handling of NaN, infinity, and -0 are quite wrong. But see below :-).
    RossH wrote:
    Yes, I keep hoping someone will write a 64 bit equivalent - it would save me a chunk of work!

    I wrote one for PropGCC (http://forums.parallax.com/showthread.php?142523-using-a-COG-as-a-floating-point-coprocessor); it handles both the 32 bit and 64 bit cases, although the 32 bit code is quite a bit slower (since it converts to 64 bits internally). Porting it to Catalina probably wouldn't be hard. I've attached a Spin version here, although there's no actual Spin interface yet (it's just the raw PASM code plus a C interface in the comments, which spin2cpp can recognize).

    Eric
  • RaymanRayman Posts: 14,670
    edited 2012-11-05 05:30
    So, is the current state that Catalina has IEEE compliant 32-bit floating point but no 64-bit. And, GCC has 32 and 64 bit, but neither is IEEE compliant?
  • David BetzDavid Betz Posts: 14,516
    edited 2012-11-05 07:02
    Rayman wrote: »
    So, is the current state that Catalina has IEEE compliant 32-bit floating point but no 64-bit. And, GCC has 32 and 64 bit, but neither is IEEE compliant?
    I believe that both the 32 and 64 bit floating point code in the PropGCC library is IEEE compliant. I think Eric was saying that the COG-based code was not and that is one reason that PropGCC doesn't use it. I'm not sure about his Double.spin code.
  • ersmithersmith Posts: 6,054
    edited 2012-11-05 08:23
    Rayman wrote: »
    So, is the current state that Catalina has IEEE compliant 32-bit floating point but no 64-bit. And, GCC has 32 and 64 bit, but neither is IEEE compliant?

    No, the reverse -- PropGCC's 32 and 64 bit code are both IEEE compliant. As far as I know it and the Double.spin/fpucog.c coprocessor that I wrote are the only IEEE compliant implementations for the Propeller. Float32 and its derivatives (including, I believe, Catalina's floating point) use 32 bit IEEE format but the operations are not quite IEEE compliant. For example, they implement a non-standard rounding mode, and do not distinguish between NaN and infinity.

    The paranoia program (http://www.netlib.org/paranoia/) is an excellent test of floating point operations, and a good way to check the quality of IEEE floating point implementations,

    Eric
  • RossHRossH Posts: 5,463
    edited 2012-11-05 15:21
    ersmith wrote: »
    Not quite, although it's not too hard to put a wrapper around it. One downside is that Float32 (and its derivatives) do not comply with the IEEE floating point standard -- the rounding is subtly wrong, and handling of NaN, infinity, and -0 are quite wrong. But see below :-).



    I wrote one for PropGCC (http://forums.parallax.com/showthread.php?142523-using-a-COG-as-a-floating-point-coprocessor); it handles both the 32 bit and 64 bit cases, although the 32 bit code is quite a bit slower (since it converts to 64 bits internally). Porting it to Catalina probably wouldn't be hard. I've attached a Spin version here, although there's no actual Spin interface yet (it's just the raw PASM code plus a C interface in the comments, which spin2cpp can recognize).

    Eric

    That's great Eric - thanks. I'll look into adding this as a Catalina option - I can probably slot it right in in place of the current floating point plugins. I think it would be slower than Catalina's current implementation even for 32 bit floats, but I know there are some people who seem to think 64 bit floats are necessary.

    Ross.
  • RaymanRayman Posts: 14,670
    edited 2012-11-05 15:26
    I think for 99.9% of the things you typically use a microcontroller for, 32-bit float is plenty.
    But, if you really want to do a nice calculator, then 64-bits would be nice.

    That said, I did program a calculator for the old Timex Datalink USB that was only 16 bits and that is good enough for many things too...
Sign In or Register to comment.