Avatar billede rdc Nybegynder
23. november 2003 - 13:56 Der er 47 kommentarer og
1 løsning

Delphi hjælp plz.

Hej allesammen


Jeg har nogle ting, som jeg simpelthen ikke kan finde ud af i delphi. Jeg har fået som opgaver at:
1. Bestem cifrene i tallenen 2^10 og 2^100 når de skrives i decimalsystemet? Find ud af hvordan tallene ser ud i det binære talsystem.

2. Hvor mange cifre er der i tallet 3^1000 når det skrives i decimalsystemet? Hvor mange af cifrene er nuller?

3. Hvor mange cifre er der i tallet 3^1000 når det skrives i det binære talsystem? Hvor mange af cifrene er nuller?

4. Hvad er ciffer nr.2006 i tallet 2^100000 når det skrives i decimalsystemet?



Jeg skal bruge kode til alle spørgsmål. da jeg ikke selv kan finde ud af det.

På Forhånd tusind tak.
Avatar billede arne_v Ekspert
23. november 2003 - 13:59 #1
Bortset fra 2^10 som kun er 1024 så kræver resten af udregningerne en
"big integer pakke".
Avatar billede rdc Nybegynder
23. november 2003 - 14:04 #2
nemlig arne_v, og det er netop der jeg står af toget. Kan simpelthen ikke finde ud af det.
Avatar billede rdc Nybegynder
23. november 2003 - 14:14 #3
Er der ikke en der kan hjælpe mig med det?
Avatar billede arne_v Ekspert
23. november 2003 - 14:16 #4
Jeg har lavet noget kode og er ved at teste.

Men det tager altså lidt tid at udregne 2^100000 !

:-)
Avatar billede arne_v Ekspert
23. november 2003 - 14:17 #5
Koden er her:

program BigPow;

{$APPTYPE CONSOLE}

uses
  SysUtils;

function numval(c : char) : integer;

begin
  numval := ord(c) - ord('0');
end;

function strval(v : integer) : char;

begin
  strval := chr(ord('0') + v);
end;

function add(v1,v2 : string) : string;

var
  res : string;
  ix1, ix2, tmp, carry : integer;

begin
  res := '';
  carry := 0;
  ix1 := length(v1);
  ix2 := length(v2);
  while (carry > 0) or (ix1 > 0) or (ix2 > 0) do begin
      tmp := carry;
      if(ix1 > 0) then begin
          tmp := tmp + numval(v1[ix1]);
          ix1 := ix1 - 1;
      end;
      if(ix2 > 0) then begin
          tmp := tmp + numval(v2[ix2]);
          ix2 := ix2 - 1;
      end;
      res := strval(tmp mod 10) + res;
      carry := tmp div 10;
  end;
  add := res;
end;

function mulpow10(v : string; pow10 : integer) : string;

var
  res : string;
  i : integer;

begin
  res := v;
  for i := 1 to pow10 do begin
      res := res + '0';
  end;
  mulpow10 := res;
end;

function mulone(v : string; num : integer) : string;

var
  res : string;
  ix, tmp, carry : integer;

begin
  res := '';
  carry := 0;
  ix := length(v);
  while (carry > 0) or (ix > 0) do begin
      tmp := carry;
      if(ix > 0) then begin
          tmp := tmp + num * numval(v[ix]);
          ix := ix - 1;
      end;
      res := strval(tmp mod 10) + res;
      carry := tmp div 10;
  end;
  mulone := res;
end;

function mul(v1,v2 : string) : string;

var
  res : string;
  i : integer;

begin
  res := '0';
  for i := 1 to length(v2) do begin
      res := add(res,mulpow10(mulone(v1,numval(v2[i])),length(v2)-i));
  end;
  mul := res;
end;

function pow(v : string; n : integer) : string;

var
  res : string;
  i : integer;

begin
  res := '1';
  for i := 1 to n do begin
      res := mul(res,v);
  end;
  pow := res;
end;

begin
  writeln(pow('2',10));
  writeln(pow('2',100));
  writeln(length(pow('3',1000)));
  writeln(pow('2',100000)[2006]);
end.
Avatar billede arne_v Ekspert
23. november 2003 - 14:25 #6
Hm. Det kører stadig.

Muligvis kræver den sidste noget mere optimeret kode end min
quick-and-dirty kode.
Avatar billede arne_v Ekspert
23. november 2003 - 14:26 #7
Avatar billede rdc Nybegynder
23. november 2003 - 15:06 #8
Det dur altså ikke.
Avatar billede arne_v Ekspert
23. november 2003 - 15:10 #9
Fordi ?
Avatar billede arne_v Ekspert
23. november 2003 - 15:27 #10
2^10 og 2^100 i binær etal system er meget nemme: 1 et tal + henholdsvis 10
og 100 nuller.
Avatar billede rdc Nybegynder
23. november 2003 - 16:57 #11
Jamen, hvordan skal jeg indtaste det i delphi?
Avatar billede arne_v Ekspert
23. november 2003 - 17:00 #12
Copy paste det ind fra browseren i din kode.

Nu har jeg lavet en console applikation og du skal nok have en
form, men selve funktionerne er jo de samme.
Avatar billede rdc Nybegynder
23. november 2003 - 17:04 #13
hmm ok tak. Nu har jeg fundet ud af det. Men din kode er meget svær at skrive kommentarer til. Vil du ikke skrive kommentar til dem?
Avatar billede arne_v Ekspert
23. november 2003 - 17:07 #14
Først skal du lige beslutte dig for om du vil satse på min kode eller
prøve noget mere professionelt (se f.eks. det link jeg angav).

Min kode er uendeligt længe om at beregne 2^100000.

Hvis du vil bruge min kose skal jeg gerne tilføje nogen kommentarer
om hvad der sker hvor.
Avatar billede arne_v Ekspert
23. november 2003 - 17:07 #15
kode (ikke kose)
Avatar billede rdc Nybegynder
23. november 2003 - 17:11 #16
Jeg vil gerne bruge din kode. For jeg er heller ikke særlig god. Så du må gerne skrive kommentarer. Pointsene er ihvertfald dine. Hvorfor tager det egentlig så lang tid for at regne 2^10000.
Avatar billede arne_v Ekspert
23. november 2003 - 17:17 #17
Det bliver nogle temmeligt store tal

Der er ca. 43000 cifre i resultatet !
Avatar billede arne_v Ekspert
23. november 2003 - 17:17 #18
Jeg vil så ligge et svar.
Avatar billede rdc Nybegynder
23. november 2003 - 17:22 #19
ok, men skriver du lige kommentar til hversætning i koden? For jeg er har virkelig brug for at læse hvad der sker i koden.
Avatar billede arne_v Ekspert
23. november 2003 - 17:26 #20
(* konvertering fra tekst tal til rigtigt tal: numval('1') giver 1 *)
function numval(c : char) : integer;

begin
  numval := ord(c) - ord('0');
end;

(* konvertering fra rigtigt tal til tekst tal: strval(1) giver '1' *)
function strval(v : integer) : char;

begin
  strval := chr(ord('0') + v);
end;

(* lig to tal sammen: add('123','10') giver '133' *)
(* standard algoritme man starter bagfra og husker menten (carry) *)
function add(v1,v2 : string) : string;

var
  res : string;
  ix1, ix2, tmp, carry : integer;

begin
  res := '';
  carry := 0;
  ix1 := length(v1);
  ix2 := length(v2);
  while (carry > 0) or (ix1 > 0) or (ix2 > 0) do begin
      tmp := carry;
      if(ix1 > 0) then begin
          tmp := tmp + numval(v1[ix1]);
          ix1 := ix1 - 1;
      end;
      if(ix2 > 0) then begin
          tmp := tmp + numval(v2[ix2]);
          ix2 := ix2 - 1;
      end;
      res := strval(tmp mod 10) + res;
      carry := tmp div 10;
  end;
  add := res;
end;

(* gang et tal med en potens af 10: mulpow('123',2) giver '12300' *)
function mulpow10(v : string; pow10 : integer) : string;

var
  res : string;
  i : integer;

begin
  res := v;
  for i := 1 to pow10 do begin
      res := res + '0';
  end;
  mulpow10 := res;
end;

(* gange strot tal med lille tal: mulone('123',2) gicer '246' *)
(* standard algoritme man starter bagfra og husker menten (carry) *)
function mulone(v : string; num : integer) : string;

var
  res : string;
  ix, tmp, carry : integer;

begin
  res := '';
  carry := 0;
  ix := length(v);
  while (carry > 0) or (ix > 0) do begin
      tmp := carry;
      if(ix > 0) then begin
          tmp := tmp + num * numval(v[ix]);
          ix := ix - 1;
      end;
      res := strval(tmp mod 10) + res;
      carry := tmp div 10;
  end;
  mulone := res;
end;

(* gang to tal sammen: mul('12','12') giver '144' *)
(* standard algoritme man tager et ciffer fra det andet tal og ganger
  med, rykker ud og ligger sammen *)
function mul(v1,v2 : string) : string;

var
  res : string;
  i : integer;

begin
  res := '0';
  for i := 1 to length(v2) do begin
      res := add(res,mulpow10(mulone(v1,numval(v2[i])),length(v2)-i));
  end;
  mul := res;
end;

(* potens funktion: pow('12',2) giver '144' *)
(* standard algoritme med en løkke som ganger det nødvendige antal gange *)
function pow(v : string; n : integer) : string;

var
  res : string;
  i : integer;

begin
  res := '1';
  for i := 1 to n do begin
      res := mul(res,v);
  end;
  pow := res;
end;
Avatar billede rdc Nybegynder
23. november 2003 - 17:30 #21
tak, men det der forstår jeg altså intet af. Jeg har brug for en kommentar til hver eneste sætning. Kunne du ikke skrive kommentar efter hvert sætning? Og når du skriver kommentar, så sætte // foran kommentarne.
Avatar billede arne_v Ekspert
23. november 2003 - 17:30 #22
En kommentar til hver sætning lyder heftigt !

Hvilke funktionerne kan du følge logikken i og hvilke kræver en
uddybende forklaring ?
Avatar billede rdc Nybegynder
23. november 2003 - 17:32 #23
En kommentar på hver linje i de her funktioner ville være dejligt:
add
mulone
mul
Avatar billede arne_v Ekspert
23. november 2003 - 17:36 #24
function add(v1,v2 : string) : string;

var
  res : string;
  ix1, ix2, tmp, carry : integer;

begin
  res := ''; // resultat = ingenting
  carry := 0; // mente = nul
  ix1 := length(v1); // start med sidste ciffer i første tal
  ix2 := length(v2); // start med sidste ciffer i andet tal
  while (carry > 0) or (ix1 > 0) or (ix2 > 0) do begin // så længe der noget
      tmp := carry; // resultat ciffer = menten
      if(ix1 > 0) then begin
          tmp := tmp + numval(v1[ix1]); // hvis der er noget tilbage af første tal lig ciffer til resulat ciffer
          ix1 := ix1 - 1;
      end;
      if(ix2 > 0) then begin
          tmp := tmp + numval(v2[ix2]);  // hvis der er noget tilbage af andet tal lig ciffer til resultat ciffer
          ix2 := ix2 - 1;
      end;
      res := strval(tmp mod 10) + res; // gem resulat ciffer (kun 1 ciffer(
      carry := tmp div 10; // resten ryger med som ny mente
  end;
  add := res;
end;
Avatar billede arne_v Ekspert
23. november 2003 - 17:49 #25
function mulone(v : string; num : integer) : string;

var
  res : string;
  ix, tmp, carry : integer;

begin
  res := ''; // resultat = ingenting
  carry := 0; // mente = nul
  ix := length(v); // start med sidste ciffer i det store tal
  while (carry > 0) or (ix > 0) do begin // så længe der er noget
      tmp := carry; // resultat ciffer = menten
      if(ix > 0) then begin
          tmp := tmp + num * numval(v[ix]); // hvis der er noget tilbage lig ciffer til resultat ciffer
          ix := ix - 1;
      end;
      res := strval(tmp mod 10) + res; // gem resultat ciffer (kun 1 ciffer)
      carry := tmp div 10; // resten ryger med som ny mente
  end;
  mulone := res;
end;
Avatar billede arne_v Ekspert
23. november 2003 - 17:53 #26
Mul forklares nok nemmest med et eksempel:

12*34 udregnes som (12*3)*10 + (12*4)*1
123*456 udregnes som (123*4)*100 + (123*5)*10 + (123*6)*1

logikken er præcis den i koden.
Avatar billede rdc Nybegynder
23. november 2003 - 22:26 #27
arne, jeg sad lige og tænkte på om det faktisk ikke kan laves på en nemmere måde?
Avatar billede arne_v Ekspert
23. november 2003 - 22:29 #28
Det er da muligt.

Jeg har svært ved at se hvordan 3^ kan løses anderledes.

Men 2^ kan man jo uhyre nemt lave en binær repæsentation af.
Problemet er at få omregnet til decimal. Integer division er
en ubehagelig operation at implementere.
Avatar billede rdc Nybegynder
23. november 2003 - 22:35 #29
Det er bare fordi at jeg synes at din kode er uhyrlang. Derfor tænkte jeg på om det ikke er muligt med en funktion istedet for så mange?
Avatar billede arne_v Ekspert
23. november 2003 - 22:44 #30
Jeg tror at de fleste andre big integer pakker er betydeligt længere.

Man kunne godt merge nogen af funktionerne men det ville da være imod
ånden i Pascal.
Avatar billede rdc Nybegynder
23. november 2003 - 22:47 #31
Jeg har lige et spørgsmål. Hvor skriver du under hver funktion til sidst:
funktionens navn:= res;
Jeg troede at man skulle skrive result:=res;
Er det bare fordi at man kan gøre begge dele?
Avatar billede arne_v Ekspert
23. november 2003 - 22:58 #32
Ja.

(jeg er lidt gammeldags)
Avatar billede rdc Nybegynder
23. november 2003 - 23:00 #33
arne, jeg fandt faktisk ligeud af at du har lavet en funktion til mig der finder resultatet. Men mine spørgsmål 2,3,4. lyder:

2. Hvor mange cifre er der i tallet 3^1000 når det skrives i decimalsystemet? Hvor mange af cifrene er nuller?

3. Hvor mange cifre er der i tallet 3^1000 når det skrives i det binære talsystem? Hvor mange af cifrene er nuller?

4. Hvad er ciffer nr.2006 i tallet 2^100000 når det skrives i decimalsystemet?

Så jeg skal faktisk bare tælle op hvormange cifre der er i tallet, og hvormange er cifrene der er nuller. Kan du hjælpe mig med det?
Avatar billede arne_v Ekspert
23. november 2003 - 23:35 #34
re 3)

Der er det:

writeln(length(pow('3',1000)));
 
svarer på !
Avatar billede arne_v Ekspert
23. november 2003 - 23:35 #35
Vrøvl det er naturligvis #2 det svarer på.
Avatar billede arne_v Ekspert
23. november 2003 - 23:36 #36
writeln(pow('2',100000)[2006]);

svarer på #4, men om det tager en time eller et år at køre ved jeg ikke !
Avatar billede arne_v Ekspert
23. november 2003 - 23:36 #37
Potenser af 3 i binært er jeg lidt usikker på !?
Avatar billede rdc Nybegynder
23. november 2003 - 23:37 #38
jamen, hvordan finder jeg så ud af hvormange af cifrene der er nuller?
Avatar billede rdc Nybegynder
23. november 2003 - 23:40 #39
Jeg har lavet det her:

procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Edit1.Text:=pow('2',10);
Form1.Edit2.Text:=pow('2',100);
Form1.Edit3.Text:=pow('3',1000);

end;

og når jeg i stedet skriver:
procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Edit1.Text:=pow('2',10);
Form1.Edit2.Text:=pow('2',100);
Form1.Edit3.Text:=length(pow('3',1000));

end;

så får jeg fejlen: [Error] Rapport.pas(165): Incompatible types: 'String' and 'Integer'
Avatar billede arne_v Ekspert
23. november 2003 - 23:43 #40
Form1.Edit3.Text:=inttostr(length(pow('3',1000)));
Avatar billede arne_v Ekspert
23. november 2003 - 23:44 #41
Jeg er som sagt lidt blank på de binære (inkl. nul) - min kode
er decimalt orienteret.

Jeg kunne ændre den til at kære binært ...
Avatar billede rdc Nybegynder
23. november 2003 - 23:47 #42
Kunne du gøre sådan så jeg også kunne finde ud af hvor mange cifra der var i tallet 3^1000 når det skrives i binære talsystem?, og regne ud hvormange af cifrene der er nuller. + regne ud hvormange af cifrene der er nuller i de andre, som du har lavet?
Avatar billede arne_v Ekspert
24. november 2003 - 00:29 #43
Hvis man får en streng med '0' og '1' i, så er det jo nemt at
tælle antal '0'.
Avatar billede arne_v Ekspert
24. november 2003 - 16:59 #44
Her er en variant som kører binært i.s.f. decimalt (grundliggende har
jeg bare erstattet 10 med 2 i de samme funktioner):

program BigPowVar;

{$APPTYPE CONSOLE}

uses
  SysUtils;

function numval(c : char) : integer;

begin
  numval := ord(c) - ord('0');
end;

function strval(v : integer) : char;

begin
  strval := chr(ord('0') + v);
end;

function add(v1,v2 : string) : string;

var
  res : string;
  ix1, ix2, tmp, carry : integer;

begin
  res := '';
  carry := 0;
  ix1 := length(v1);
  ix2 := length(v2);
  while (carry > 0) or (ix1 > 0) or (ix2 > 0) do begin
      tmp := carry;
      if(ix1 > 0) then begin
          tmp := tmp + numval(v1[ix1]);
          ix1 := ix1 - 1;
      end;
      if(ix2 > 0) then begin
          tmp := tmp + numval(v2[ix2]);
          ix2 := ix2 - 1;
      end;
      res := strval(tmp mod 2) + res;
      carry := tmp div 2;
  end;
  add := res;
end;

function mulpow2(v : string; pow2 : integer) : string;

var
  res : string;
  i : integer;

begin
  res := v;
  for i := 1 to pow2 do begin
      res := res + '0';
  end;
  mulpow2 := res;
end;

function mulone(v : string; num : integer) : string;

var
  res : string;
  ix, tmp, carry : integer;

begin
  res := '';
  carry := 0;
  ix := length(v);
  while (carry > 0) or (ix > 0) do begin
      tmp := carry;
      if(ix > 0) then begin
          tmp := tmp + num * numval(v[ix]);
          ix := ix - 1;
      end;
      res := strval(tmp mod 2) + res;
      carry := tmp div 2;
  end;
  mulone := res;
end;

function mul(v1,v2 : string) : string;

var
  res : string;
  i : integer;

begin
  res := '0';
  for i := 1 to length(v2) do begin
      res := add(res,mulpow2(mulone(v1,numval(v2[i])),length(v2)-i));
  end;
  mul := res;
end;

function pow(v : string; n : integer) : string;

var
  res : string;
  i : integer;

begin
  res := '1';
  for i := 1 to n do begin
      res := mul(res,v);
  end;
  pow := res;
end;

function fastpow(v : string; n : integer) : string;

var
  res : string;

begin
  writeln(v,' ',n);
  if n=1 then begin
      res := v;
  end else begin
      if odd(n) then begin
        res := mul(v,fastpow(mul(v,v),n div 2));
      end else begin
        res := fastpow(mul(v,v),n div 2);
      end;
  end;
  fastpow := res;
end;

begin
  writeln(pow('2',10));
  writeln(pow('2',100));
  writeln(length(pow('3',1000)));
end.
Avatar billede rdc Nybegynder
24. november 2003 - 23:12 #45
ok, kan du ikke lave et eksempel på hvordan man beregner antal 0'er?
Avatar billede arne_v Ekspert
25. november 2003 - 05:47 #46
Der løber du jo bare strengen igennem og tæller.

s := pow('3',1000);
nzero := 0;
for i := 1 to length(s) do
  if s[i]='0' then
      nzero := nzero + 1;
Avatar billede arne_v Ekspert
28. november 2003 - 21:38 #47
OK ?
Avatar billede arne_v Ekspert
08. december 2003 - 22:47 #48
??
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester