Visit PersonalMicroCosms.com

Go to the C# Programmable Calculator Website

Description

C# Programmable Calculator is a Reverse Polish Notation (RPN) calculator that can have custom buttons, programmed in C#.

Required Hardware and Software

C# Programmable Calculator requires a machine running .NET version 1.1 or later and Windows 2000, XP, or later.

Introduction

C# Programmable Calculator has a Number Entry Area where new numbers are entered. The pre-defined buttons perform basic mathematical operations. Programmable buttons can be programmed with C#:

Programmable buttons are programmed with an integrated source code editor:

Examples

RPN calculators require numbers to be entered before the operation is performed. Operations have no priority - they are performed in the order entered. Consequently RPN calculators do not need parentheses.

Since numbers must be entered before the operation to be performed, to evaluate 1 + 2:

press the 1 button
press the Enter button
press the 2 button
press the + button


The result, 3, is left on the stack.

More Examples

ExpressionHow to Evaluate
17 * (3 + 4)17 Enter 3 Enter 4 + *
3.14 * 123.4^23.14 Enter 123.4 X^2 *
(3^2 * (7^2 - 8)) / 57 X^2 8 - 3 Enter X^2 * 5 /

Pressing Buttons

There are several different ways to press C# Programmable Calculator's buttons:

All buttons can be selected with the mouse.

Digits, Enter, +, -, *, /, and the decimal point (".") can be typed from the keyboard or the numeric keypad. If you use the numeric keypad, make sure that the Num Lock light is on.

<- can be entered by typing the Backspace key.

Built-In Buttons

ButtonAcceleratorWhat it does
DropAlt+r Removes the topmost stack item.
SwapAlt+S Exchanges the topmost two stack items.
Clear Ent.Alt+l Clears the number entry area.
Ch. SignAlt+h Changes the sign of the topmost stack item (i.e. multiplies it by -1). Use this button to enter negative numbers.
RecipAlt+p Replaces the topmost stack item with its reciprocal (i.e. divides 1 by it).
SqrtAlt+q Replaces the topmost stack item with its square root.
Clear AllAlt+A Removes all stack items and clears the number entry area.
EnterAlt+E or Enter key Moves the number from the number entry area to the top of the stack or duplicates the item on the top of the stack.
X ^ 2Alt+X Replaces the topmost stack item with its square (i.e. multiplies the topmost stack item by itself).
Y ^ XAlt+Y Raises the next-to-topmost stack item to the power of the topmost stack item.
Ent. Hex...Alt+t Prompts the user for a hexadecimal (base 16) number. If the user enters one it is placed on the top of the stack.
Hex2DecAlt+D Converts the topmost stack item from hexadecimal (base 16) format to decimal (base 10) format.
Dec2HexAlt+c Converts the topmost stack item from decimal (base 10) format to hexadecimal (base 16) format.
// Divides the second-to-topmost stack item by the topmost stack item.
** Multiplies the second-to-topmost stack item by the topmost stack item.
-- Subtracts the topmost stack item from the second-to-topmost stack item.
++ Adds the second-to-topmost stack item to the topmost stack item.
0-90-9 Appends the digit to the right of the number entry area.
.. Appends the decimal point to the right of the number entry area.
<--Backspace Removes the rightmost character from the number entry area.

Pre-Programmed Buttons

TabButtonWhat it does
Main FloatingPoint Displays numbers in the stack with an arbitrary number of digits to the right of the decimal point.
FixedPoint Displays numbers in the stack with the specified number of digits to the right of the decimal point and thousands separators.
% Converts a number into a percentage. For example, converts 5 to 0.05.
SciNot Converts the specified number and power of ten to a number in scientific notation.
IntegerPart Computes the whole number portion of a floating-point number.
FractionalPart Computes the fractional portion of a floating-point number.
Round Rounds the specified number to the closest whole number.
Floor Computes the largest whole number less than or equal to the specified number.
Ceiling Computes the smallest whole number greater than or equal to the specified number.
Math |x| Converts the number to a positive number if it's negative.
Fib Computes the specified Fibonacci number.
n! Computes the factorial of n (e.g. n!).
Pi Returns Pi (3.14159265358979).
LN Computes the natural logarithm of the specified number.
e^X Computes the inverse natural logarithm of the specified number.
e Computes Euler's constant.
Log Computes the decimal logarithm of the specified number.
10^X Computes the inverse decimal logarithm of the specified number.
FindFraction Computes a fraction that approximates a rational number.
Random Computes a pseudorandom number between 0 and 1.
Trig Sin Computes the sine of the angle (which must be in radians).
Cos Computes the cosine of the angle (which must be in radians).
Tan Computes the tangent of the angle (which must be in radians).
ASin Computes the arcsine.
ACos Computes the arccosine.
ATan Computes the arctangent.
Cosh Computes the hyperbolic cosine.
Sinh Computes the hyperbolic sine.
Tanh Computes the hyperbolic tangent.
ACosh Computes the inverse hyperbolic cosine.
ASinh Computes the inverse hyperbolic sine.
ATanh Computes the inverse hyperbolic tangent.
Angles Radians Converts an angle expressed in degrees into the equivalent angle in radians.
Degrees Converts an angle expressed in radians into the equivalent angle in degrees.
DMS2Decimal Converts an angle expressed in degrees, minutes, and seconds into the equivalent angle in decimal format. For example, converts 23 degrees, 59 minutes, 13 seconds to 23.9869444444444.
AngleBetweenLocations Returns the angle subtended at the center of the earth by the two positions expressed as latitude and longitude. See DistanceBetweenLocations, below
DistanceBetweenLocations Computes the great circle distance between two cities, given their latitudes and longitudes.
Memory Store Stores the value in the specified register.
Recall Retrieves the value in the specified register.
Finance Amortize Computes a loan payment schedule. Note: the amortization schedule is only valid in the USA.
Dates & Times Now Returns the current date and time (in local timezone).
Today Returns the current date (in the local timezone). Time is midnight.
ToUniversalTime Converts the specified date and time to Tniversal Time (GMT).
ToLocalTime Converts the specified date and time from Universal Time to the local time zone.
GetDate If the user selects a date, a DateTime object will be placed on the stack.

If the user cancels the dialog box, a null value will be placed on the stack.
GetDateRange If the user selects a date range, a SelectionRange object will be placed on the stack. To extract the start and end date from the SelectionRange object, use SelectionRange.Begin and SelectionRange.End.

If the user cancels the dialog box, a null value will be placed on the stack.
AddDays Adds the specified number of days to a date.
SubtractDays Subtracts the specified number of days from a date.
SubtractDates Subtracts the dates and returns the resulting TimeSpan.

Note: Any pre-programmed function can be replaced with your own function or deleted.

Programmable Buttons

To program an existing programmable button, right-click the programmable button. An integrated source code editor will be launched, allowing you to modify that button's function.

To program a new button, press the Edit Functions button and enter one or more functions. When you press the OK button the new functions will be automatically assigned to programmable buttons.

A programmable function's button is only enabled when the stack contains the correct number of arguments that the function expects, in the correct datatypes. In other words, if a function's button requires two double-precision floating-point numbers, there must be at least two items on the stack, and the top two must be of type double.

To supply a function with arguments, add items to the stack in the order that they appear in the function declaration. For example, consider the following function:

public static double SciNot(double n, double PowerOf10)

// Allow the user to enter numbers in scientific notation.
// Return n * 10 ^ PowerOf10.
    
{
  return n * Math.Pow(10.0, PowerOf10);
}

Enter the number first, then enter the power of 10. For example, enter 6.0221367 * 1023 as follows:

6.0221367 Enter 23 Enter SciNot

Advanced Editing Features

The integrated source code editor has a multiple-line indent and unindent feature. To indent multiple lines, select the lines and press the Tab key. To unindent multiple lines, select the lines and press Shift+Tab.

Canceling Lengthy Calculations

If a function is taking too long, press Esc to cancel it. Note: you may need to single-click the icon in the taskbar before pressing Esc:

Specifying Tabs

Programmable buttons are arranged into tabs. Use the Tab attribute to specify the names of tabs, and the order in which they appear. For example:
[assembly:Tab("Main",          1)]
[assembly:Tab("Math",          2)]
[assembly:Tab("Trig",          3)]
[assembly:Tab("Angles",        4)]
[assembly:Tab("Memory",        5)]
[assembly:Tab("Finance",       6)]
[assembly:Tab("Dates & Times", 7)]

In the Tab attribute, the first argument specifies the name of the tab. The second argument specifies the order in which it appears, from left to right.

Specifying Programmable Buttons

To specify the tab to which a programmable button belongs, use the Button attribute. For example:
// Display numerical values as floating point.
[Button("Main")]
public static void FloatingPoint()
{
  iapi.DisplayFormat = "";
}

The first argument to the Button attribute specifies the name of the tab to which the programmable button belongs. The second argument specifies the button text. This argument is optional and only needs to be specified if the button text differs from the method's name. For example:

[Button("Math", "n!")]
public static long Factorial(int n)

In this case the second argument is specified since the button text, "n!", is different than the method's name ("Factorial").

Objects

Objects are displayed in the stack by calling their ToString() method. Your functions can return objects of any class, or values of any primitive type (int, bool, float, double, byte, etc).

Saving the Stack

C# Programmable Calculator automatically saves the stack contents every time you close the program, and restores the stack when you run it later. One exception: If objects of user-defined classes are stored on the stack, the stack will not be restored when the program is run again.

The Global Variable Array

You can store and retrieve values from the global variable array as follows:
int index;
Object o;
...
globals[index] = o;
The Store and Recall programmable functions use the global variable array to store and recall values.

Using .NET Assemblies

By default, your custom functions can only the System namespace and a few others. To access other namespaces, first add the appropriate "using" statement, e.g.:

using System.Windows.Forms;

At this point, if the corresponding assembly has not been added, you'll get an error message like the following:

To add the assembly, press Configure Assemblies in the Error dialog box, or select Options / Settings in the main window:

Argument Conversion

When possible, values on the stack are converted to be compatible with function arguments. If the stack contains a floating-point value and the corresponding function argument is an integral type, the floating-point value is truncated and converted into that integral type.

Checking for Numeric Overflows

C# code ignores numerical overflow by default. If you want your code to throw an exception when an overflow happens, use one of the following techniques:

Technique #1: Check for numeric overflow

Select Options / Settings. Select the Misc. tab and check the Check for numeric overflow checkbox. This setting affects all of your functions.

Technique #2: Checked Block

To enable overflow checking for specific functions, use checked blocks as follows:

public static long Factorial(int n)
    
// Calculates n! using a recursive algorithm.
    
{
  long result = 1;

  // By default, C# code will not throw
  // exceptions when overflows happen.  To
  // ensure that an exception is thrown when
  // overflows occur, enclose the code in a 
  // checked block.

  checked
  {
    if (n > 1)
    {
      result = n * Factorial(n - 1);
    }
  }
    
  return result;
}

Checked expressions can also be enclosed in parenthesis, for example:

public static void Overflow()
{
  short x = 32000;
  short y = 32000;
      
  short z = checked((short) (x + y));
}

User-Defined Classes

Example

You can create and use user-defined classes like the following:

public class UserDefined
{
  public UserDefined(int intValue)
  {
    this.intValue = intValue;
  }

  public override String ToString()
  {
    return intValue.ToString();
  }

  public int intValue;
}

public UserDefined pushUserDefined()
{
  return new UserDefined(42);
}

public int popUserDefined(UserDefined userDefined)
{
  return userDefined.intValue;
}

Caveats

If you call a function that places a user-defined object on the stack, and then make changes to functions (by pressing the Edit Functions button, or by adding or deleting any assemblies), any user-defined objects on the stack cannot be passed to functions.

In this situation you'll get the following error message:

One or more of the stack values did not match the corresponding argument types expected by method.

To resolve this issue, simply press the Clear All button. This will remove the incompatible objects from the stack. When user-defined objects are subsequently pushed on the stack they can be passed to functions.

In other words, you can't store user-defined objects on the stack, and then make changes to their class(es), and then expect the old, out-of-date, objects to be compatible with methods that are expecting the new objects.

Finally, if there are user-defined objects on the stack when the program is closed, when it is run again the stack will be empty.

The CSPCUtil Utility Library

C# Programmable Calculator includes an assembly named CSPCUtil.dll that provides some useful utility functions that you can use in your programmable functions:

Method/Property Description Arguments Return Value
Util.Prompt Prompts the user for a value of the specified type.
1: Form mainForm Parent form of this dialog box. Use iapi.MainForm for this argument.
2: String caption Caption displayed on the dialog box
3: String prompt Text displayed above the TextBox
4: String initialValue Initial text in the TextBox
5: Type valueType Data type of value
If the user presses OK, the text in the TextBox is converted to an object of the type specified by valueType and that object is returned. If the user presses Cancel, a null object is returned.
Util.DisplayTextLines Displays the specified lines of text in a dialog box.
1: Form mainForm Parent form of this dialog box. Use iapi.MainForm for this argument.
2: String caption Caption displayed on the dialog box
3: String[] textLines Lines of text to display in the dialog box
n/a (this is a void method)
Util.DisplayBrowser Displays the specified HTML or URL in a web browser window in a dialog box.
1: Form mainForm Parent form of this dialog box. Use iapi.MainForm for this argument.
2: String caption Caption displayed on the dialog box
3: String content Contains the HTML or the URL to display
4: bool html Specify a value of true if the content argument contains HTML. If the content argument contains a URL specify a value of false.
n/a (this is a void method)
Util.DisplayBrowser Displays the specified HTML or URL in a web browser window in a dialog box, optionally maximized.
1: Form mainForm Parent form of this dialog box. Use iapi.MainForm for this argument.
2: String caption Caption displayed on the dialog box
3: String content Contains the HTML or the URL to display
4: bool html Specify a value of true if the content argument contains HTML. If the content argument contains a URL specify a value of false.
5: bool fullScreen Specify whether or not the browser form should launch in maximized mode.
n/a (this is a void method)
Util.GetDate Displays the specified HTML or URL in a web browser window in a dialog box, optionally maximized.
1: Form mainForm Parent form of this dialog box. Use iapi.MainForm for this argument.
2: String caption Caption displayed on the dialog box
3: DateTime defaultDate Specifies the date that is initially selected.
Returns a DateTime object if the user selects a date.

If the user cancels the dialog box a null value will be returned.
Util.GetDateRange Displays the specified HTML or URL in a web browser window in a dialog box, optionally maximized.
1: Form mainForm Parent form of this dialog box. Use iapi.MainForm for this argument.
2: String caption Caption displayed on the dialog box
3: DateTime defaultDate Specifies the date that is initially selected.
4: int maxSelectionCount Specifies the maximum number of days that can be selected.
If the user selects a date range, a SelectionRange object will be returned. To extract the start and end date from the SelectionRange object, access the Begin and End properties, respectively.

If the user cancels the dialog box, a null value will be returned.
GraphicsForm Constructor Constructs a GraphicsForm object which allows you to display graphics in a modal dialog box.
1: String caption Caption displayed on the dialog box
2: Size graphicsSize Width and height of graphics
n/a (this is a constructor)
GraphicsForm.ShowDialog Launches the modal graphics dialog box. Call this method after you've finished drawing graphics.
1: Form mainForm Parent form of this dialog box. Use iapi.MainForm for this argument.
n/a (this is a void method)
GraphicsForm.GraphicsObject Property The GraphicsObject readonly property returns a Graphics object that can be used to draw graphics on the Form.

Be sure to finish drawing all graphics before calling ShowDialog.
n/a a Graphics object

Examples

Prompt

PromptForPrice launches a dialog box with an initial value of 1.00 displayed. When the user presses the OK button a double value is returned containing the specified value. If the user presses Cancel, null is returned.

public double PromptForPrice()
{
  return (double) Util.Prompt(iapi.MainForm, "Enter Price", "Price:", "1.00", typeof(double));
}

DisplayTextLines

FibonacciReport generates a textual report displaying the Fibonacci numbers from 1 to max. It uses an ArrayList to store the lines that will be used in the report because ArrayLists can dynamically grow. It's easy to convert an ArrayList in to a String array, just use the ArrayList.ToArray method.

public void FibonacciReport(int max)
{
  ArrayList lines = new ArrayList();

  for (int i = 1; i <= max; i++)
  {
    lines.Add("Fib(" + i + ") = " + Fib(i).ToString());
  }

  Util.DisplayTextLines(iapi.MainForm, "Fibonacci Numbers", (String[]) lines.ToArray(typeof(String)));
}

DisplayBrowser

BrowserDemo first launches the dialog box displaying the www.PersonalMicroCosms.com website. After the user presses the Close button, the dialog box is launched again, displaying the specified HTML.

public static void BrowserDemo()
{
  // Display the www.PersonalMicroCosms.com website:
  Util.DisplayBrowser(iapi.MainForm, "Personal MicroCosms", "www.PersonalMicroCosms.com", false);

  // Display HTML text:
  String htmlText = "<HTML><BODY><P>THIS IS A PARAGRAPH</P></BODY></HTML>";

  Util.DisplayBrowser(iapi.MainForm, "HTML", htmlText, true);
}

GraphicsForm

graphicsDemo creates a GraphicsForm, launches it, and then draws random lines with random colors.

public void graphicsDemo()
{
  const int width  = 2000;
  const int height = 2000;

  using (GraphicsForm gf = new GraphicsForm("interesting graphic", new Size(width, height)))
  {
    Graphics g = gf.GraphicsObject;
  
    Random r = new Random();
  
    for (int i = 0; i < 1000; i++)
    {
      int x1 = r.Next(width);
      int x2 = r.Next(width);
  
      int y1 = r.Next(height);
      int y2 = r.Next(height);
  
      g.DrawLine(new Pen(Color.FromArgb(r.Next(256), r.Next(256), r.Next(256))), x1, y1, x2, y2);
    }
  
    gf.ShowDialog(iapi.MainForm);
  }
}

The ICSPCAPI API

C# Programmable Calculator has an API that can be called from your programmable functions. To access this API, use the iapi member and call the following methods:

Method/Property Description Arguments Return Value
DisplayFormat Property The DisplayFormat property specifies how numerical values will be displayed.

Assign this property to an empty string for default formatting.

Assign to "F{digits}" for fixed-point display, where {digits} is the number of digits to the right of the decimal point. For example, use "F2" to display currency amounts.

Use "N{digits}" for fixed-point display with thousands separators, for example, use "N2" to display currency amounts.
n/a the display format String
FullDisplayFormat Property The FullDisplayFormat readonly property returns the display format specified by the DisplayFormat property, but in a format that can be used by String.Format(), for example "{0:F2}".

NOTE: This display format string is used to format numerical values in the stack.
n/a the full display format String.
MainForm Property The MainForm readonly property returns C# Programmable Calculator's main form. Use this form to ensure that message boxes and dialog boxes are children of the main form. n/a the main form

Debugging Features

Assert

In your functions you can use Debug.Assert to ensure that specified conditions are true. If they are ever not true, a message box will be displayed, which will help you find the error in your code.

For example, since dividing by zero is an error, the following function uses Assert to verify that the denominator is never zero. If it ever is, an error message will be displayed that pinpoints the precise location of the problem in your code.

public double divide(double numerator, double denominator)
{
  // denominator must not be zero!

  Debug.Assert(denominator != 0.0);

  return numerator / denominator;
}

To enable Asserts in your code, make sure you've included the following using statement:

using System.Diagnostics;

Then select Options / Settings and select the Misc. tab and make sure the Allow debugging features checkbox is checked.

Trace

You can add code to your functions that will output trace messages for debugging purposes. For example:

public void TRACEDemo(double d)
{
  Trace.WriteLine("User entered a value of " + d.ToString());
}

The trace messages will appear in a separate window.

To enable Asserts in your code, make sure you've included the following using statement:

using System.Diagnostics;

Then select Options / Settings and select the Misc. tab and make sure the Allow tracing features checkbox is checked. Then select View / Trace Window, which will launch the dialog box in which the trace messages will appear.


Visit PersonalMicroCosms.com

Go to the C# Programmable Calculator Website