HP Forums

Full Version: AriCalculator is a home made pocket calculator.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4
You should avoid converting from BCD to binary and back. This guarantees that you'll not get correct results for things you should. Arithmetic directly in decimal should be used. It will save a lot of multiplications and divisions in the conversion.

As for the initial estimate, you don't need to handle such a wide range. You only need to handle a mantissa between 0.1 and 1 and normalisation gives this automatically. For an even exponent, the exponent of the result is half that of the original and this doesn't alter the mantissa of the result. For an odd exponent, it is more troublesome.

This is the method described in Properly Rounded Variable Precision Square Root by T. Hull and A. Abrham from ACM Transactions on Mathematical Software, Vol 11 #3, September 1985:

f = mantissa of x  (which must be normalised 0.1 <= x < 1)
e = exponent of x
if e is even then
    approximation = 0.259 + 0.819 * f
    f = f / 10  (i.e. a one digit shift, in BCD four bits)
    e = e + 1
    approximation = 0.0819 + 2.59 * f

Apply Newton's method: \( approximation = 0.5 \left( approximation + \frac{f}{approximation} \right) \) until convergence. The final result is \( approximation \times 10^{\frac{e}{2}} \). I.e. the approximation with the exponent set to e / 2. Correct rounding requires an extra step: you need to square the result and the result ±1 ULP to see which value is indeed most accurate.

There are others approaches if this isn't suitable.

Converting to binary is unavoidable - my multiplication and division algorithms are based on "shift and add" methods . Also I haven't observed any incorrect results arising from converting between BCD and binary. All arithmetic is integer so there are no issues with numbers that cannot be expressed exactly in binary.

e.g. 1.2 * 0.3 =

0001 0010 FF * 0000 0011 FF

The BCD values in the mantissas are converted to binary, giving:

0000 1100 FF * 0000 0011 FF.

The "shift and add" algorithm is applied to find the product of the mantissas, and the exponents are added, giving:

0010 0100 FE = 0.36

This is then converted back to BCD:

0011 0110 FE

If the conversion to binary were not made, then:

1.2 * 0.3 = 0001 0010 FF * 0000 0011 FF = 0011 0110 FE = 0.54
Ahhh, that makes sense. Don't worry about it -- I assumed you used a binary floating point format which would have problems.

I have finally finished coding the scientific functions - all that remains is to include logic to handle x^y when x <= 0 since I used x^y = e^(ylnx). I want to test the algorithms. One test is:

arcsin (arccos (arctan (tan (cos (sin 9)))))

Any other tests people would recommend?
I wouldn't bother with the forensic test unless you are aiming for correct rounding. It isn't that interesting.

Try things like:
  • Trig functions as their argument approaches multiples of pi/2.
  • That sin(x) = sin(-x) for all x.
  • Trig functions for huge arguments (to validate your modulo reduction).
  • Log as its argument approaches zero and one.
  • Square root as its argument approaches zero and one.

I'm sure a lot of other cases will come to mind once I post Smile

Powers of large numbers. Are the mantissa correct and the correct exponent displayed?
The painted keypad:

[Image: 48246864407_9e960f92d4_c.jpg]
This article lists the parameters used in several linear congruential random number generators.

The AUR for the 50g states that the calculator uses a linear congruential generator. Anyone know the parameters?

Edit: I found the answer here
There are much better generators than linear congruential.

The xorshift+ generator is fast and reasonable, the xorshift* generator relies on a long multiplication, so it isn't as fast on many devices.

The WP 34S uses the Tausworthe generator from the GNU Scientific Library, very fast, very long period and maximally equidistributed. The paper by Pierre L’Ecuyer is enlightening and includes the derived generator on the second last page.

Thanks Pauli,

I'll use the linear congruential generator for now, despite its faults, as I can implement it easily by writing a keystroke program, saving the hex codes in a table, and executing the program whenever the random number key is pressed on the calculator. Not as fast as an assembly language implementation but allows me to quickly add new functions to the firmware. I've done the same for the hyperbolic functions.

I've been using the CodeWarrior IDE (no code limits for assembly language programs) and have written about 45Kb of assembly code to create a programmable calculator with basic scientific functions, and hope to implement complex numbers and an exact mode in under 64Kb by the end of the year.

What algorithm did you use for the gamma function? Also what microcontroller does the WP 34S use, how large is the firmware and what development tools did you use?
Hello Daniel,

Wouldn't it be easier (and more random) to extract random numbers from hardware? On the AriCalculator for example, you can measure A/D conversion noise, PLL jitter, and the timestamp of key strokes.

I decided to implement the 64-bit xorshift generator described on page 4 of George Marsaglia's "Xorshift RNG's". It involves shifting the seed 13 bits to the left, followed by 7 bits to the right and then 17 bits to the left, with a bit-wise exclusive OR performed after each shift. Any non-zero value can be used as the seed, and according to the author it passes all tests of randomness, except the binary rank test.
Sorry, missed this.

(02-05-2018 04:25 AM)Dan Wrote: [ -> ]What algorithm did you use for the gamma function?

Lanczos. Tuned to the precision we were using.

Quote:Also what microcontroller does the WP 34S use

Atmel AT91SAM7L128

Quote:how large is the firmware

A bit over 122kbytes. The rest of flash is used for the RAM backup and the libraries.

Quote:what development tools did you use?

Most of the development was done off device. I used Linux & MacOS. Some was done using Windows. For the firmware, we built on Windows using the Yagarto GCC 4.6.0, other versions and other compilers we tried later exposed a compiler bug so we reverted and didn't try again - if it isn't broken and all that.

I have now implemented complex numbers:

[Image: 48246888537_90ede619df.jpg]

[Image: 48246806476_c1464e1c4d.jpg]

The functions available in complex mode are: /,*,-,+ and conjugate, modulus, conversion to polar form and conversion to Cartesian/rectangular form.

I can now add new functions to the calculator by copying the hex codes of programs written on the calculator to the firmware, which is what I did for |z|. I will implement sqrt(z) in a similar way.
I've not read the entire thread just yet, but picking up on this:

Quote:@KeithB: The laser engraved labels are better readable once they have been colored with acrylic paint.

Or you could use coloured acrylic (or another sort of opaque coloured filter) behind the clear laser cut letters, a work neighbour here who makes has a laser cutter and does this all day for Raspberry Pi products he makes for his company.

I like it, it reminds me of an Mk14 ...........
The AriCalculator has an NXP S12 microcontroller with 240kB FLASH. I am considering porting the firmware to the NXP S12XEP100, which has an almost identical instruction set but more FLASH memory (1MB).

I can program it in assembly using the CodeWarrior IDE, which is free. CodeWarrior also has a "full-chip simulation" mode that allows you to debug your code without downloading it to the actual device, thereby saving the FLASH on the device from repeated writes.

I am wondering if there are similar microcontroller development environments, i.e. ones that are:

1) free
2) allow you to code in assembly with no code limitations, and
3) feature a simulation mode
Regarding programming everything in assembly... I used to do that (I started to think about building my own calculator at the end of the 90s), I started with the 68HC11 (a subset of what you have), H8/300H (I had math routines, GUI and plots working), SH-1, AVR. I stopped there and went to C. I can test on the PC and have HAL code for the different microcontrollers I use nowadays: Cortex-M3, M4 and PIC32 (MIPS), and x86. Even a PIC32 at 16 MHz has enough speed that assembly is not required.

I think that MPLABX lets you simulate (for the PIC32), many people does not like it, I used to use netbeans so it is a familiar environment for me.
I've been busy with the coconut (HP-41) and Saturn cores. I'm developing a "platform" to be able to test the saturn on real hardware.

One aspect that interests me is power consumption:

On the PIC32, I was switching between a low power 32 kHz and a 8 MHz RC oscillator. The limited amount of pins on the DIP28 package forced me to drop an external 32 kHz crystal for the low power oscillator. The timing is the derived from the current selected oscillator forcing me to re-set every time a clock switch occurs Sad.

How did you approach this topic ? What are your figures ?

Yeah assembly has its advantages, I'd just combine it with C for the user interface, I find it tedious to do all that in assembly.

The people who programmed the original TI-85 did it also in assembly (and the derivatives, of course). They used bank switching to increase code size, very interesting. At least the HC12 has bank switch built-in in the opcode map, very nice.

Why do you want to use a part with 1 MB flash ? You have use 70 kBytes of 240... just asking

The AriCalculator's CPU runs at 50MHz using the S12G's PLL and internal RC oscillator as reference clock. The MCU's run current is below 17mA. The clocks can be turned of when the device is idle and the USB port is unplugged, reducing the current consumption to about 25uA. The calculator can be then woken up through the keyboard, even when the system clocks are stopped. The display draws 320uA in operation, but can be put in a low power mode as well. The FTDI USB/SCI converter is externally supplied by the USB bus. The calculators MCU and display are powered through a boost converter with the start-up voltage of 0.65V, so it does drain its batteries pretty empty, before it stops working.

While the current S12G240 MCU is small, cheap, and power efficient, the S12XE100 would add some nice features to the calculator:

- 100MHz CPU with extended instruction set
- 32Kb of RAM
- EEPROM emulation which works like a non-volatile RAM
- second CPU (XGATE) to handle all I/O
- external bus interface to add even more RAM
Doing something similar here Smile

I'm planning on replacing the firmware in a Swiss Micros DM11 so that everything is native, no Nut emulation, so hopefully much faster.

I have +, -, *, /, sqrt, sin, cos, tan, ln, log, and e^x working in my decimal floating point library so far. 21-24 digits accuracy, so within the framework I'd set myself (20 display digits, 24 digits internally). 10^x is up next and then asin, acos and atan. I'd rather get the hyperbolic trig functions done with CORDIC if possible but if not I'll just calculate them using e^x.
Pages: 1 2 3 4
Reference URL's