Board index » delphi » having problem with compiler directives and variable limits

having problem with compiler directives and variable limits

I have taking a Pascal programming class for about three months.

I wrote a factoring algorithm. It works fine, up to about the
1 billion range. I decided to use real types like extended
and double to enable the factoring of ridiculously high numbers;
enabling their use with the  {$N+} directive.
This is in Borland Turbo Pascal v7.0 for Dos.  The complier gets
over the directive and the program runs the same,
but I still don't have capacity for factoring numbers higher than
about 1 billion. Can some one help me?

here's my code:

Program Calculate_Factors (input, output);
{$N+}

Uses CRT;

Type Exponential = record
        base:      real;                      {integer}
        exponent:  integer;    end;

Type Factor_Array = Array [1..10] of Exponential;

Var  choice:           Char;
     n,number,m:       double;  {extended;}
     e,q,f,s:          integer;
     factor:           Factor_Array;

BEGIN  ClrScr; Repeat  Q:=1;  if q>1 then  writeln('Please Enter a
Positive Integer less than 2.5 billion.');  Write('Number to be factored
--> '); Readln(number);  Q:=Q+1;

      n:=trunc(number);  s:=1;  f:=2;  e:=0;  m:=Sqrt(n);

      For Q:= 1 to 10 Do
        Begin      factor[Q].base:=0; factor[Q].exponent:=0;       End;

      While f<=m do
        Begin

            While (trunc(n) Mod f)=0 Do
              Begin
                e:= e+1;
                n:=(trunc(n) Div f);
              End;

            If e>0 Then
               Begin
                 factor[s].base:=f;
                 factor[s].exponent:=e;
                 e:=0;
                 s:=s+1;
                 m:=Sqrt(n);
               End; {Ends If}

            If f=2
               Then f:=3
               Else f:=f+2;

        End; {end of While-do statement}

          If n<>1 Then
             Begin
               factor[s].base:=n;
               factor[s].exponent:=1;
             End;

      Writeln('The Prime Factors of ',number:0:0,' are:'); q:=1;

      Repeat
        Writeln('(',factor[q].base:0:0,'^',factor[q].exponent:0,')');
q:=q+1;
      Until (factor[q].base=0) or (factor[q].exponent=0);

  Writeln('Press Any Key to Rerun or <q> to quit.':78);writeln;writeln;

      choice:=(readkey);

Until choice In ['q','Q'];

END.

End *************8

-------------------==== Posted via Deja News ====-----------------------
      http://www.dejanews.com/     Search, Read, Post to Usenet

 

Re:having problem with compiler directives and variable limits


Quote
>Subject: having problem with compiler directives and variable limits
>From: ben.wooda...@nocturnal.com
>Date: Mon, Nov 10, 1997 03:58 EST
>Message-id: <879028719.15...@dejanews.com>

>I have taking a Pascal programming class for about three months.

>I wrote a factoring algorithm. It works fine, up to about the
>1 billion range. I decided to use real types like extended
>and double to enable the factoring of ridiculously high numbers;
>enabling their use with the  {$N+} directive.

Does your teacher actually require you to factor number larger than 1
 billion?!?

Since you're only dealing with integers you should use the Comp type instead,
 which is basically an Extended type that holds integral values only.

Quote
>This is in Borland Turbo Pascal v7.0 for Dos.  The complier gets
>over the directive and the program runs the same,
>but I still don't have capacity for factoring numbers higher than
>about 1 billion. Can some one help me?

>here's my code:

>Program Calculate_Factors (input, output);
>{$N+}

>Uses CRT;

>Type Exponential = record
>        base:      real;                      {integer}
>        exponent:  integer;    end;

>Type Factor_Array = Array [1..10] of Exponential;

>Var  choice:           Char;
>     n,number,m:       double;  {extended;}
>     e,q,f,s:          integer;
>     factor:           Factor_Array;

>BEGIN  ClrScr; Repeat  Q:=1;  if q>1 then  writeln('Please Enter a
>Positive Integer less than 2.5 billion.');  Write('Number to be factored
>--> '); Readln(number);  Q:=Q+1;

>      n:=trunc(number);  s:=1;  f:=2;  e:=0;  m:=Sqrt(n);

>      For Q:= 1 to 10 Do
>        Begin      factor[Q].base:=0; factor[Q].exponent:=0;       End;

>      While f<=m do
>        Begin

>            While (trunc(n) Mod f)=0 Do

Your problem's right there!  Trunc always returns a Longint, so you're back to
 where you've started.

But of course, if you don't use trunc you can't use MOD, since MOD only accepts
 integer types, and the largest integer type available is Longint (Comp isn't
 an integer type even though it only holds integers).

Therefore you'll have to use the following approach to see if n is divisible by
 f:  If n is divisble by f, that means n/f is an integer, which means the
 fractional part of n/f is zero.  Got it?  (Look in the help file for the
 function Frac(x) if you haven't seen it...)

Quote
>              Begin
>                e:= e+1;
>                n:=(trunc(n) Div f);
>              End;

Same thing here.  Get rid of the Trunc and just use / .

By the way, you should increase the number of elements in your factor array to
 accomodate for larger numbers.  The largest number representable in the Comp
 type is 1 less than 2 to the 63rd , which is about 10 to the 19th.

- Show quoted text -

Quote

>            If e>0 Then
>               Begin
>                 factor[s].base:=f;
>                 factor[s].exponent:=e;
>                 e:=0;
>                 s:=s+1;
>                 m:=Sqrt(n);
>               End; {Ends If}

>            If f=2
>               Then f:=3
>               Else f:=f+2;

>        End; {end of While-do statement}

>          If n<>1 Then
>             Begin
>               factor[s].base:=n;
>               factor[s].exponent:=1;
>             End;

>      Writeln('The Prime Factors of ',number:0:0,' are:'); q:=1;

>      Repeat
>        Writeln('(',factor[q].base:0:0,'^',factor[q].exponent:0,')');
>q:=q+1;
>      Until (factor[q].base=0) or (factor[q].exponent=0);

>  Writeln('Press Any Key to Rerun or <q> to quit.':78);writeln;writeln;

>      choice:=(readkey);

>Until choice In ['q','Q'];

>END.

>End *************8

>-------------------==== Posted via Deja News ====-----------------------
>      http://www.dejanews.com/     Search, Read, Post to Usenet

Other Threads