[M3devel] LONGINT problem?

Ken Durocher kcdurocher at gmail.com
Fri Jul 15 01:00:11 CEST 2011


Sorry, to clarify, the LONGINT code does NOT give the correct output, but
the INTEGER code DOES.

I did not write this C code, but it's output is the same as all the other
examples (there is a Java example too, if you want that):

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

/* should be 64-bit integers if going over 1 billion */
typedef unsigned long xint;
#define FMT "%lu"

xint total, prim, max_peri;
xint U[][9] =  {{ 1, -2, 2,  2, -1, 2,  2, -2, 3},
{ 1,  2, 2,  2,  1, 2,  2,  2, 3},
{-1,  2, 2, -2,  1, 2, -2,  2, 3}};

void new_tri(xint in[])
{
int i;
xint t[3], p = in[0] + in[1] + in[2];

if (p > max_peri) return;

prim ++;

/* for every primitive triangle, its multiples would be right-angled too;
 * count them up to the max perimeter */
total += max_peri / p;

/* recursively produce next tier by multiplying the matrices */
for (i = 0; i < 3; i++) {
t[0] = U[i][0] * in[0] + U[i][1] * in[1] + U[i][2] * in[2];
t[1] = U[i][3] * in[0] + U[i][4] * in[1] + U[i][5] * in[2];
t[2] = U[i][6] * in[0] + U[i][7] * in[1] + U[i][8] * in[2];
new_tri(t);
}
}

int main()
{
xint seed[3] = {3, 4, 5};

for (max_peri = 10; max_peri <= 100000000; max_peri *= 10) {
total = prim = 0;
new_tri(seed);

printf( "Up to "FMT": "FMT" triples, "FMT" primitives.\n",
max_peri, total, prim);
}
return 0;
}

The output from that code is:

Up to 10: 0 triples, 0 primitives.
Up to 100: 17 triples, 7 primitives.
Up to 1000: 325 triples, 70 primitives.
Up to 10000: 4858 triples, 703 primitives.
Up to 100000: 64741 triples, 7026 primitives.
Up to 1000000: 808950 triples, 70229 primitives.
Up to 10000000: 9706567 triples, 702309 primitives.
Up to 100000000: 113236940 triples, 7023027 primitives.

Note this output corresponds with the INTEGER output.

On Thu, Jul 14, 2011 at 5:17 PM, Jay K <jay.krell at cornell.edu> wrote:

>  Can you isolate if the problem is the formating/printing, or if it is in
> the computation?
> i.e.:
>
> Use "unsafe" and print out a little hex dump of the integer/longint
> variables?
>
> As well, what does LONGINT on a 64bit machine do? Eh..well, it might work,
> it might not.
> Doesn't really matter. Let's focus on non-working 32bit machine with
> LONGINT.
>
> Also, please confirm which is the right, i.e. by writing it in C.
> Also, maybe just try to format as unsigned/hex using the safe interfaces?
> Also, this will be good to add to our automated tests. Assuming it doesn't
> run too slowly.
> Assuming it reproduces for anyone else (sorry, a bit rude of me).
>
> Later, thank you,
>  - Jay
>
>
> ------------------------------
> Date: Thu, 14 Jul 2011 16:26:05 -0500
> From: kcdurocher at gmail.com
> To: m3devel at elegosoft.com
> Subject: [M3devel] LONGINT problem?
>
>
> I was writing a program to calculate "Pythagorean triples" recursively, and
> ran into a problem.  Here's the program:
>
> MODULE PyTriples EXPORTS Main;
>
> IMPORT IO, Fmt;
>
> VAR tcnt, pcnt, max, i: LONGINT;
>
> PROCEDURE NewTriangle(a, b, c: LONGINT; VAR tcount, pcount: LONGINT) =
>   VAR perim := a + b + c;
>   BEGIN
>     IF perim <= max THEN
>       pcount := pcount + 1L;
>       tcount := tcount + max DIV perim;
>       NewTriangle(a-2L*b+2L*c, 2L*a-b+2L*c, 2L*a-2L*b+3L*c, tcount,
> pcount);
>       NewTriangle(a+2L*b+2L*c, 2L*a+b+2L*c, 2L*a+2L*b+3L*c, tcount,
> pcount);
>       NewTriangle(2L*b+2L*c-a, b+2L*c-2L*a, 2L*b+3L*c-2L*a, tcount,
> pcount);
>     END;
>   END NewTriangle;
>
> BEGIN
> i := 100L;
>
> REPEAT
>   max := i;
>   tcnt := 0L;
>   pcnt := 0L;
>   NewTriangle(3L, 4L, 5L, tcnt, pcnt);
>   IO.Put(Fmt.LongInt(i) & ": " & Fmt.LongInt(tcnt) & " Triples, " &
>     Fmt.LongInt(pcnt) & " Primitives\n");
>   i := i * 10L;
> UNTIL i = 10000000L;
>
> END PyTriples.
>
> This outputs:
>
> 100: 17 Triples, 7 Primitives
> 1000: 325 Triples, 70 Primitives
> 10000: 0858 Triples, 703 Primitives
> 100000: 40701 Triples, 7024 Primitives
> 1000000: 808950 Triples, 70229 Primitives
>
> However, if I just use INTEGER on a 64 bit machine, I get the proper
> output:
>
> 100: 17 Triples, 7 Primitives
> 1000: 325 Triples, 70 Primitives
> 10000: 4858 Triples, 703 Primitives
> 100000: 64741 Triples, 7026 Primitives
> 1000000: 808950 Triples, 70229 Primitives
>
> Note how 10000 and 100000 are different. The code is literally exactly the
> same, only with LONGINT replaced by INTEGER.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20110714/a279df77/attachment-0002.html>


More information about the M3devel mailing list