[M3devel] LONGINT problem?
Coleburn, Randy
rcolebur at SCIRES.COM
Fri Jul 15 23:54:41 CEST 2011
Ken:
With all due respect, I don't think Daniel is on the right track.
I note that one of our developers checked in a fix that may solve your problem.
There seems to have been a problem in formatting the output where certain digits got messed up.
Try updating your system with this new fix and run your program again. It may solve your problem.
Regards,
Randy Coleburn
________________________________
From: Ken Durocher [kcdurocher at gmail.com]
Sent: Friday, July 15, 2011 5:53 PM
To: Daniel Alejandro Benavides D.
Cc: m3devel; Coleburn, Randy
Subject: Re: [M3devel] LONGINT problem?
I just checekd, and I can confirm that the LONGINT version of the code produces INCORRECT results on a 32 bit system, as well as a 64 bit system. Both are running Linux, with cm3 5.8.6
On Thu, Jul 14, 2011 at 8:30 PM, Daniel Alejandro Benavides D. <dabenavidesd at yahoo.es<mailto:dabenavidesd at yahoo.es>> wrote:
Hi all:
the problem as I see is that your program isn't typed for any platform in specific just to give you the best answer, then I would stick to the original and track down the source of the problem (this is very point of type checking, and e.g extended static checking if I may say so, the need to verify your statements, the other approach is too cumbersome, i.e make it believe it works when it doesn't). IMHO this a symptom of UNSAFE type checking problem, rather of programming or programmer error.
I hope to be clarified about this, as far as I know LONGINT isn't INTEGER but a bigger or equal type (a bigger INTEGER) which translates better to be a super type, since it isn't I wonder why is that needed a different type checker for that (we can transform INTEGER to be the true super type and LONGINT to be a subtype), can't we make the same checking and just range check everything else (so it doesn't bother to rewrite every platform code, a bad symptom certainly, yet I approve the change in the language SPEC but not its type checking).
Thanks in advance
--- El jue, 14/7/11, Coleburn, Randy <rcolebur at SCIRES.COM<mailto:rcolebur at SCIRES.COM>> escribió:
De: Coleburn, Randy <rcolebur at SCIRES.COM<mailto:rcolebur at SCIRES.COM>>
Asunto: Re: [M3devel] LONGINT problem?
Para: "m3devel" <m3devel at elegosoft.com<mailto:m3devel at elegosoft.com>>, "Ken Durocher" <kcdurocher at gmail.com<mailto:kcdurocher at gmail.com>>
Fecha: jueves, 14 de julio, 2011 18:15
Ken:
On what platform (OS and CPU) are you building and running your Modula-3 program?
Support for LONGINT is a relatively new addition to CM3, so it is possible that something is broken. Perhaps your program can help us track it down.
I haven’t checked thru your program yet, but the fact that it gives the right answer using INTEGER, but not when using LONGINT, seems to point to the LONGINT implementation as a potential problem source we should investigate.
Regards,
Randy Coleburn
From: Ken Durocher [mailto:kcdurocher at gmail.com<mailto:kcdurocher at gmail.com>]
Sent: Thursday, July 14, 2011 7:00 PM
To: Jay K
Cc: m3devel
Subject: Re: [M3devel] LONGINT problem?
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<http://mc/compose?to=jay.krell@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<http://mc/compose?to=kcdurocher@gmail.com>
To: m3devel at elegosoft.com<http://mc/compose?to=m3devel@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/20110715/ac532803/attachment-0002.html>
More information about the M3devel
mailing list