Author Topic: _Integer64 arithmetic misbehaves  (Read 1356 times)

0 Members and 1 Guest are viewing this topic.

Offline Jon Richfield

  • Newbie
  • Posts: 14
_Integer64 arithmetic misbehaves
« on: October 30, 2019, 11:03:50 am »
Unless of course I am misbehaving...

Some months ago I was messing about with primorials, can't remember why, and things went pear-shaped. wrong results, in spite of trying _unsigned etc. (Unsigned would have suited me fine, maybe I was tinkering with encryption, in which case truncation on overflow would be perfect, and I had a vague idea that in a previous version I did actually get truncation, but I am unsure.)

Anyway, I scribbled a bit of code to test the stuff (in case I errr... was fouling up) and it seemed unfortunately not to be the case, because then I could have fixed it myself.

OK, so here follows the test source. Please run it for yourself, either to prove that I fouled up (I hope!) or to consider fixing up the QB arithmetic. (I am running on a W10 desktop with a plain Intel processor, plenty of memory etc, and all the QB I have run so far has behaved itself much better than I have.) Here goes:
OPTION BASE 0
Top = 14
DIM Primorial(Top), Prims(Top), P AS _UNSIGNED _INTEGER64
P = 2 ^ 62
PRINT "Start:"
PRINT USING "##########################"; P
PRINT USING "##########################"; P * 2
PRINT USING "##########################"; P + P
PRINT USING "##########################"; P * 4
PRINT USING "##########################"; P + P + P + P
DEFLNG I-N
DATA 0002,0003,0005,0007,0011,0013,0017,0019,0023,0029,0031,0037
DATA 0041,0043,0047,0053,0059,0061,0067,0071,0073,0079,0083,0089
DATA 0097,0101,0103,0107,0109,0113,0127,0131,0137,0139,0149,0151
DATA 0157,0163,0167,0173,0179,0181,0191,0193,0197,0199,0211,0223
FOR I = 1 TO Top
    READ Prims(I)
NEXT
Primorial(0) = 1
FOR I = 1 TO Top
    Primorial(I) = Primorial(I - 1) * Prims(I)
    PRINT USING "##########################"; Prims(I), Primorial(I), Primorial(I) \ Primorial(I - 1)
NEXT
END

You will note that at the start of the code, the pure binary arithmetic has behaved well: values for 2^62 ok. 2^63 OK, allowing for overflow into the sign position, and 2^64 might as well give 0, given that the only 1-bit had gone to bit heaven. I reckon I could live with that one way or another, but have a look at the primorials.

The code is simple, if undocumented: multiply successive primes from a READ list, giving successive primorials. At the end of the line, divide the putative primorial by the previous primorial, which should give the current prime, but in several cases does not, because the current primorial is wrong.

Up to primorial 19 it is fine, but primorial 23 comes out 6 short, which error propagates to higher levels with elaborations.

Please assist, someone.

Offline Jon Richfield

  • Newbie
  • Posts: 14
Re: _Integer64 arithmetic misbehaves
« Reply #1 on: October 30, 2019, 11:43:57 am »
Replying (partly) to my own question.

I had a sudden satori. I removed the Deflng statement, and inserted a _Define A-Z _Unsigned _integer64 statement at the top.

That seems to have worked magic on automatic intermediate values, and suddenly my test code at least seems to work correctly.

It seems a rather brutal solution, but not impossible.

Is there any policy concerning intermediate values that needs re-thinking? If not, where do I find a statement on the principles QB64 adheres to?

Thanks for attention so far.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: _Integer64 arithmetic misbehaves
« Reply #2 on: October 30, 2019, 01:10:22 pm »
So many times I have confessed my problems to others and then the answer pops into my head.

Something about writing it out to present gets another part of the brain working...

Welcome to the forum Jon

Wait you got _UNSIGNED _INTEGER64 to work? I was trying to find the highest integer QB64 could do, all positive would be fine... man I am out of time to finish!
« Last Edit: October 30, 2019, 01:17:20 pm by bplus »

Offline Jon Richfield

  • Newbie
  • Posts: 14
Re: _Integer64 arithmetic misbehaves
« Reply #3 on: October 30, 2019, 02:06:50 pm »
Hi bplus, thanks for the welcome; Much appreciated.

As for finding the maximal value, I found _integer64 quite domesticated once I learnt not to be careless about mixing it with other modes. Works well with both integer arithmetic and logical functions such as XOR.

To see the maximim, try this quick scribble:
_DEFINE A-Z AS _UNSIGNED _INTEGER64
CLS
PRINT "Possible values of numbers with increasing numbers of repeated 1-bits from 1 to 64 in unsigned words."
I = 1
FOR J = 1 TO 80
    PRINT USING "########################"; J, I
    I = I + I + 1
    IF J MOD 20 = 0 THEN
        INPUT "Press Enter-key to continue"; x$
        LOCATE CSRLIN - 1, 1
    END IF
NEXT
PRINT "Note how the number remains constant once the 64-bit word is full."