Post Reply 
New WP34S unit
11-05-2023, 07:53 PM
Post: #21
RE: New WP34S unit
Thanks Nigel for your great effort.

I checked it's working as you say, a "Too long" message when more than 64 bits are being entered, the problem is that WSIZE is not being taken into account so when WSIZE < 64 there is still digit rotation until the 64 bits are reached.
Find all posts by this user
Quote this message in a reply
11-05-2023, 08:01 PM
Post: #22
RE: New WP34S unit
(11-05-2023 07:53 PM)ebs Wrote:  Thanks Nigel for your great effort.

I checked it's working as you say, a "Too long" message when more than 64 bits are being entered, the problem is that WSIZE is not being taken into account so when WSIZE < 64 there is still digit rotation until the 64 bits are reached.

That is how the previous code on the calculator works. You can enter up to 12 digits, whatever the word size. I wanted to change things as little as possible - principle of least surprise! Do you think this should be changed?

Nigel (UK)
Find all posts by this user
Quote this message in a reply
11-05-2023, 08:36 PM
Post: #23
RE: New WP34S unit
(11-05-2023 08:01 PM)Nigel (UK) Wrote:  That is how the previous code on the calculator works. You can enter up to 12 digits, whatever the word size. I wanted to change things as little as possible - principle of least surprise! Do you think this should be changed?

Nigel (UK)

Yeah, I think we are defining the behaviour beyond the original. In the WP34S manual the only paragraph related to input of integers is "Note numeric input is limited to 12 digits in all integer bases." and you already expanded this Smile. There is nothing in the manual about digits being truncated.

In HP16C there is not digit truncation nor rotation during input, you just cannot enter more digits when the limit is reached. I think this is the least confusing behaviour. But unfortunately my understanding of the WP34S code is limited so I don't know if this is easy or difficult to achieve (taking into account the memory limitations), so I leave final the decision to you Smile.
Find all posts by this user
Quote this message in a reply
11-06-2023, 12:50 AM
Post: #24
RE: New WP34S unit
Another possibility would be to let insert the extra digits when WSIZE <= n and get them when WSIZE > n.
I will explain:

Initially hex, WSIZE = 8, LZON

Current behaviour:
type AF3 -> you get F3
change to WSIZE = 16
you get 00F3

Proposed behaviour:
type AF3 -> you get F3
change to WSIZE = 16
you get 0AF3

Do you think this could be useful? Again it depends if it's easy to implement.
Find all posts by this user
Quote this message in a reply
11-06-2023, 12:21 PM
Post: #25
RE: New WP34S unit
Release 3921 now uploaded. This flashes the "Too Long Error" message when the key just pressed would cause the number of bits required to exceed the current word size. Let me know if there are any problems.

I think the idea about keeping bits beyond the current word size, but hiding them, is not going to work. Supposing you did 2 5 - and instead of -3 you got 7, because the first 2 was really 12? Or you shift 0110 right by one bit and instead of 0011 you get 1011, for a similar reason? I think that people limit word size because the bits beyond the word size really aren't there in a particular application, and they want to do binary (etc.) arithmetic subject to this restriction.

Release 3921 also includes changes to the V2.2 branch (!) which now allows you to build this ancient firmware once more. It's not ideal to have two such different things in the same commit, but I doubt anyone will mind. I'm not expecting this branch to return to life, but it's nice to leave it in a working state for posterity.

Nigel (UK)
Find all posts by this user
Quote this message in a reply
11-06-2023, 11:48 PM
Post: #26
RE: New WP34S unit
Nigel, it's working perfectly (I tested 3.3 3921).

As a side note, in 2c, 16, dec, if you try to enter 65535 you get -1, but I don't consider this a bug, it's just how the negative representation works.

Thanks a lot.
Find all posts by this user
Quote this message in a reply
11-08-2023, 03:34 AM
Post: #27
RE: New WP34S unit
https://sourceforge.net/p/wp34s/code/HEA...realbuild/ New r3922

(11-06-2023 12:21 PM)Nigel (UK) Wrote:  Release 3921 now uploaded. This flashes the "Too Long Error" message when the key just pressed would cause the number of bits required to exceed the current word size. Let me know if there are any problems.

I think the idea about keeping bits beyond the current word size, but hiding them, is not going to work. Supposing you did 2 5 - and instead of -3 you got 7, because the first 2 was really 12? Or you shift 0110 right by one bit and instead of 0011 you get 1011, for a similar reason? I think that people limit word size because the bits beyond the word size really aren't there in a particular application, and they want to do binary (etc.) arithmetic subject to this restriction.

Release 3921 also includes changes to the V2.2 branch (!) which now allows you to build this ancient firmware once more. It's not ideal to have two such different things in the same commit, but I doubt anyone will mind. I'm not expecting this branch to return to life, but it's nice to leave it in a working state for posterity.

Nigel (UK)
Find all posts by this user
Quote this message in a reply
11-08-2023, 10:45 PM
Post: #28
RE: New WP34S unit
Nigel, could you explain briefly r3922? I cannot see a difference. Thanks.
Find all posts by this user
Quote this message in a reply
11-08-2023, 11:39 PM
Post: #29
RE: New WP34S unit
(11-08-2023 10:45 PM)ebs Wrote:  Nigel, could you explain briefly r3922? I cannot see a difference. Thanks.

It's all in Sourceforge so you can see exactly what changed; below is the file with the relevant changes:

https://sourceforge.net/p/wp34s/code/392...50023:3921

Description was "Minor bug fix (long integer entry) and code rewriting."
Visit this user's website Find all posts by this user
Quote this message in a reply
11-09-2023, 08:13 AM
Post: #30
RE: New WP34S unit
Yes, I know, what I meant is that I don't understand the change itself.

In the code there is a comment:

Code:

CmdLineIntFlag = 1; // flag tells set_int_x to use CmdLineIntSign as the sign
              // so if -12h is being entered -12 gets copied, not EE
              set_int_x(CmdLineInt, buf);

But if I enter -12 in hex, I still get FF...EE what is correct in 2c as far as I know.
Find all posts by this user
Quote this message in a reply
11-09-2023, 12:04 PM
Post: #31
RE: New WP34S unit
(11-09-2023 08:13 AM)ebs Wrote:  Yes, I know, what I meant is that I don't understand the change itself.

In the code there is a comment:

Code:

CmdLineIntFlag = 1; // flag tells set_int_x to use CmdLineIntSign as the sign
              // so if -12h is being entered -12 gets copied, not EE
              set_int_x(CmdLineInt, buf);

But if I enter -12 in hex, I still get FF...EE what is correct in 2c as far as I know.

Hello! The code quoted above is in the function void format_display(char *buf) in the file display.c. The job of this function is to produce a string of characters that correspond to the number currently in the display. It's used by the Qt and IOS emulators when copying the displayed number to the clipboard. It's not compiled in either the Windows build or the real calculator, so the change in it doesn't affect either of these.

The function first looks to see if there is a non-empty command line - i.e., if a number is currently being entered. If there isn't, it simply converts the contents of the X-register to an appropriate string of characters. If a number is being entered, it copies the command line contents to an output buffer.

With the new intmode code, the command line no longer contains the characters that are entered (in integer modes) so the code had to be changed. The particular change made here means that if the user is in the process of entering a negative number, e.g., -12, then calling format_display() will return "-12", rather than "FFEE". Once the number is entered it will become FFEE, depending on the settings, and that is what will be returned by format_display() in that case.

If I make any future changes I'll try to be clearer about exactly what is affected.

Thank you for your question!

Nigel (UK)
Find all posts by this user
Quote this message in a reply
11-09-2023, 12:59 PM
Post: #32
RE: New WP34S unit
(11-09-2023 12:04 PM)Nigel (UK) Wrote:  It's used by the Qt and IOS emulators when copying the displayed number to the clipboard. It's not compiled in either the Windows build or the real calculator, so the change in it doesn't affect either of these.

Thanks Nigel, that explains why I didn't see any difference Big Grin
Find all posts by this user
Quote this message in a reply
11-11-2023, 06:44 PM
Post: #33
RE: New WP34S unit
New release r3923: the decimal-to-fraction conversion algorithm has been replaced by an improved version taken from the C47 project (on the SwissMicros forum), in the WP34S and WP34C branches.

The WP34C branch is now up-to-date with the long integer entry code.

For both branches I've #defined IGNORE_INVALID_FRACTIONS to save a few hundred bytes; the recent code additions have cost some space.

Nigel (UK)
Find all posts by this user
Quote this message in a reply
11-12-2023, 01:50 AM (This post was last modified: 11-12-2023 01:57 AM by ebs.)
Post: #34
RE: New WP34S unit
Hi Nigel, something is not working properly with fractions on 3923. I'm testing with real hardware.

If I try to input 1/3 and then enter, after some seconds I get
   

From that point the calculator is working erratic until a reset is done (as the message suggests).
Find all posts by this user
Quote this message in a reply
11-12-2023, 08:22 AM
Post: #35
RE: New WP34S unit
Confirmed! Sorry. It doesn't happen on the emulator and I'm sure it didn't happen on the hardware until I turned on the space-saving IGNORE_INVALID_FRACTIONS option, which now has a rather ominous sound. I'll sort this out later today. Huge thanks!

Nigel (UK)
Find all posts by this user
Quote this message in a reply
11-12-2023, 10:46 PM (This post was last modified: 11-12-2023 10:48 PM by Nigel (UK).)
Post: #36
RE: New WP34S unit
That was fun. It turns out that the problem wasn't IGNORE_INVALID_FRACTIONS, nor any error in my code. It's just that the new algorithm converges almost unbelievably slowly, taking more than 3000 iterations to conclude that 0.333333333 is 1/3 (when DENMAX is 9999). This isn't noticeable for the computer versions, and neither is it a problem for the WP34S port on the DM42. But it causes the real calculator to crash - I think that the battery voltage drops and causes a reset. (My batteries aren't new.)

I didn't notice the problem when testing because I was checking the behaviour of numbers like pi and e (for which the algorithm works well) rather than numbers like 1/3 0r 0.01 (for which it doesn't).

So I've abandoned the C47 algorithm and written a new one, using information at this link. The result combines much greater speed with the increased precision of the C47 algorithm. No longer will your calculator tell you that the best approximation to \(\pi\) with DENMAX=100 is \(3\frac17\); instead you'll be correctly told that it is \(3 \frac{14}{99}\). Your calculator won't crash either (I hope).

The code is in the function decNumber2Fraction in decn.c; it's hard to read because it uses decNumbers, but there are comments explaining how it works.

Nigel (UK)
Find all posts by this user
Quote this message in a reply
11-12-2023, 11:47 PM
Post: #37
RE: New WP34S unit
I thought the old algorithm was using the continued fraction expansion and that was having problems.


Pauli
Find all posts by this user
Quote this message in a reply
11-13-2023, 12:11 PM
Post: #38
RE: New WP34S unit
(11-12-2023 11:47 PM)Paul Dale Wrote:  I thought the old algorithm was using the continued fraction expansion and that was having problems.


Pauli
That is correct. The algorithm I'm now using extends the continued fraction approach so that the problems go away! At least, I hope so. Here are the details.

We can write the continued fraction representation for a number \(x\) as
\[ (a_0; a_1, a_2, a_3, \ldots),\]
so that
\[x = a_0+{1\over{a_1+\displaystyle{1\over{a_2+\ldots}}}}.\]
These numbers are easy to generate: take the floor of \(x\), record it, find the reciprocal of the fractional part, and repeat. The fractions corresponding to each stage of the continued fraction can be generated recursively from this list of numbers: if the fraction is \(h/k\), then
\[h_n = a_nh_{n-1}+h_{n-2},\quad k_n = a_nk_{n-1}+k_{n-2}.\]
For example, the representation for \(\pi\) is \((3; 7, 15, 1, 292,\ldots)\), leading to fractions
\[3, {22\over 7}, {333\over 106}, {355\over 113},\ldots\]
These are called convergents: each has the property that it is closer to \(\pi\) than any other fraction with the same or smaller denominator.

I believe that the existing WP34S algorithm uses this method. When DENMAX=100 it returns 22/7. However, this isn't the fraction closest to \(\pi\) with denominator less than 100; that best fraction is 311/99. So the WP34S algorithm is not perfect, although it is short, fast, and never wildly wrong.

The C47 algorithm improves on this by bracketing the number \(x\) by a pair of rational numbers, \(a/b\) and \(c/d\). It repeatedly calculates the mediant \((a+c)/(b+d)\) of these numbers, updates the bracket, and repeats the process. This works well for "awkward" numbers like \(\pi\), but is really slow for numbers like 0.5 or 0.3333333333. This lack of speed is an issue on the WP34S.

What I've done is to use the idea of "semiconvergents" discussed in this Wikipedia page. Suppose you reach a stage where the denominator of a convergent is greater than DENMAX. Instead of going back to the previous convergent you can instead generate "semiconvergents" which have denominators intermediate in value. Each of these semiconvergents is a best rational approximation to \(x\), in the sense that it is closer to \(x\) than any fraction with the same or smaller denominator. My algorithm chooses the semiconvergent with the largest denominator less than or equal to DENMAX: in the case of \(\pi\) and DENMAX=100, this is 311/99.

A semiconvergent is the fraction
\[{h\over k}={mh_{n-1}+h_{n-2}\over mk_{n-1}+k_{n-2}},\]
where \(m\) is an integer between \(a_n/2\) and \(a_n\). It's easy to find the value of \(m\) that gives the largest denominator less than DENMAX, so finding the best semiconvergent is fast. There are a few conditions on \(m\), described on the Wikipedia page, but the whole process is straightforward and seems to work well.

Wikipedia doesn't include proofs of the assertion that these semiconvergents are best rational approximations, but there is such a proof here. I've scanned it but I haven't worked through it in detail.

I like this method because, assuming that Wikipedia is correct, it gives the best rational approximation in a relatively small number of steps. In particular it doesn't crash the WP34S hardware, which is a big point in its favour!

Nigel (UK)
Find all posts by this user
Quote this message in a reply
11-13-2023, 09:35 PM
Post: #39
RE: New WP34S unit
Tested r3924, it's working fine. Thanks Nigel.
Find all posts by this user
Quote this message in a reply
11-14-2023, 12:12 AM
Post: #40
RE: New WP34S unit
Interesting twist. Any chance you'd consider contributing this back to the C47 project?

Pauli
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)