Autor Beitrag
Marco D.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Sa 18.11.06 14:37 
Ich muss die alternierende Quersumme einer Zahl berechnen. Das macht die Routine Foo:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
function Foo(int: integer): integer;
 var i: integer; s: string;
  begin
    result := 0;
    //alle veränderten Stellen durchgehen
    for i := 1 to 5 do
    begin
      if (i mod 2 = 0then
      begin
        s := inttostr(int);
        result := result + strtoint(s[5 - i])
      end
      else begin
        s := inttostr(int);
        result := result - strtoint(s[5 - i])
      end;
    end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(inttostr(Foo(36036)));
end;

Aber es kommt immer am Ende des letzten Durchlaufes der for-Schleife eine Meldung:
Zitat:

---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Project1.exe ist eine Exception der Klasse EConvertError aufgetreten. Meldung: ''
---------------------------
OK Hilfe
---------------------------

Das kann ich mir nicht erklären. :gruebel:

Mehr über das Verfahren gibts hier.

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Sa 18.11.06 14:49 
Ein String beginnt immer bei 1.
So nun läuft dein i von 1 bis 5 - letzlich steht da also:
ausblenden Delphi-Quelltext
1:
result := result - strtoint(s[5 - 5])					

5 - 5 ist null, daher nicht definiert ;)

grüße marc
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Sa 18.11.06 14:52 
user profile iconMarc. hat folgendes geschrieben:
Ein String beginnt immer bei 1.
So nun läuft dein i von 1 bis 5 - letzlich steht da also:
ausblenden Delphi-Quelltext
1:
result := result - strtoint(s[5 - 5])					

5 - 5 ist null, daher nicht definiert ;)

grüße marc

:autsch: Klar! Also muss die Schleife von 0-4 gehen?

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Sa 18.11.06 14:52 
Perfekt es klappt!

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Sa 18.11.06 14:54 
Oder du ziehst nicht i von 5 ab, sondern von 6:
ausblenden Delphi-Quelltext
1:
result := result - strtoint(s[6 - i])					


6 - 1 = 5
6 - 2 = 4
...
6 - 5 = 1


//edit: kommt zwars selbe raus, allerdings negativ ;)
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Sa 18.11.06 14:58 
user profile iconMarc. hat folgendes geschrieben:
Oder du ziehst nicht i von 5 ab, sondern von 6:
ausblenden Delphi-Quelltext
1:
result := result - strtoint(s[6 - i])					


6 - 1 = 5
6 - 2 = 4
...
6 - 5 = 1


//edit: kommt zwars selbe raus, allerdings negativ ;)


Ich muss das Prinzip nochmal neu überdenken, vielleicht kann man die Schleife noch optimieren. ;)
Kann man das ganze auch lösen, ohne Stringroutinen zu benutzen? Wie könnte man dann z.B. auf die 5 Ziffer zugreifen?

Moderiert von user profile iconAXMD: Beiträge zusammengefasst

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 18.11.06 17:10 
yep, mit einen datentyp der die werte auf einen festen platz stellt, z.b. BCD (binary coded decimal). <HTH>
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Sa 18.11.06 17:30 
user profile iconGrenzgaenger hat folgendes geschrieben:
yep, mit einen datentyp der die werte auf einen festen platz stellt, z.b. BCD (binary coded decimal). <HTH>

Noch nie von gehört. Kannst du mir das mal bitte erklären? :p

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 18.11.06 17:45 
hier sind je 2 Ziffern in einem byte codiert im high und low nibble. der processor kennt das format und kann damit normal rechnen. das bcd format wird normal für kaufmännische anwendungen eingesetzt, da hier der prozessor nicht keine rundungsdifferenzen auftreten, im gegendsatz zu fliesskommazahlen. kannst ja mal kurz im netz (z. B. de.wikipedia.org/wiki/BCD-Code) lurken unter BCD oder in der delphi hilfe.

alternativ hier einen etwas optimierteren code deiner routine
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
FUNCTION Foo(int: INTEGER): INTEGER;
VAR
 i, l: INTEGER;
 s: string;
BEGIN
 s := IntToStr(int); l := length(s);  result := 0//vorbelegung
 FOR i := 1 TO l DO  //alle veränderten Stellen durchgehen
  IF (i MOD 2 = 0THEN
   result := result - (INTEGER(s[1 + l - i]) - 48)
  ELSE
   result := result + (INTEGER(s[1 + l - i]) - 48);
END;


//Edit: Klammern ergänzt


Zuletzt bearbeitet von Grenzgaenger am Sa 18.11.06 18:12, insgesamt 4-mal bearbeitet
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Sa 18.11.06 17:52 
ausblenden Delphi-Quelltext
1:
Result := Result - INTEGER(s[1 + l - i]) - 48					

Würdest du mir diese Zeile bitte erklären? Vor allem die 48.
Und warum ermittelst du die Länge von s bevor s die Zahl zugewiesen wird? Was genau ist denn bei diesem Verfahren nun der Vorteil?

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 18.11.06 18:02 
hast recht, das mit der längengabe, hat sich 'n fehler beim layouten eingeschlichen, der ist korrigiert.

das mit dem 48 lässt sich aufklären mit 'n blick auf www.torsten-horn.de/techdocs/ascii.htm, da ich jetzt einfach die zahl, die im string steht manuell umrechne, damit erspare ich mir den aufwand über den strtoint... das integer sagt dass es sich um kein zeichen sondern um einen integer handelt, wenn ich von dem integer dann 48 abziehe komme ich ganz normal auf den wert der ziffer... das andere ist die indexierung. plus 1, da der string jetzt ab 1 und nicht mehr bei 0 beginnt, ist hier für den index eine stelle hinzuzufügen.

<HTH>
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Sa 18.11.06 18:06 
user profile iconGrenzgaenger hat folgendes geschrieben:
hast recht, das mit der längengabe, hat sich 'n fehler beim layouten eingeschlichen, der ist korrigiert.

das mit dem 48 lässt sich aufklären mit 'n blick auf www.torsten-horn.de/techdocs/ascii.htm, da ich jetzt einfach die zahl, die im string steht manuell umrechne, damit erspare ich mir den aufwand über den strtoint... das integer sagt dass es sich um kein zeichen sondern um einen integer handelt, wenn ich von dem integer dann 48 abziehe komme ich ganz normal auf den wert der ziffer... das andere ist die indexierung. plus 1, da der string jetzt ab 1 und nicht mehr bei 0 beginnt, ist hier für den index eine stelle hinzuzufügen.

<HTH>

Danke, ich schau's mir mal an. ;)

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: So 19.11.06 15:47 
user profile iconMarco D. hat folgendes geschrieben:
Kann man das ganze auch lösen, ohne Stringroutinen zu benutzen? Wie könnte man dann z.B. auf die 5 Ziffer zugreifen?


Ich weiß nicht, ob dus noch brauchst, aber ich hab hier ne Funktion. Frage ist, ob damit irgendwas schneller wird.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
function GetStelle(X:int64; St:byte):byte;
var f:double;
begin
  f:= X;
  while st>0 do begin
    f:= f / 10;
    dec(st);
  end;
  Result:= trunc(Frac(f)*10);
end;


Meine Testergebnisse:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
4. Stelle von 13549586 ist 9
6. Stelle von 13549586 ist 5
15. Stelle von 13549586 ist 0
0. Stelle von 13549586 ist 0
1000000 Durchlaeufe Stelle 8....
196,957007397027 ms


Optimieren könnte man noch, indem man durch 10^St dividiert, statt einzeln. Wirklich schneller ist das aber auch nicht, die 1 Million Durchläufe kommt dann auf 168 ms.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
uses Math;

function GetStelle2(X:int64; St:byte):byte;
var f:double;
begin
  f:= x*Power(10,-st);
  Result:= trunc(Frac(f)*10);
end;

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: So 19.11.06 15:50 
Danke, aber das hat sich erledigt. ;)

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: So 19.11.06 16:53 
user profile iconMartok hat folgendes geschrieben:
4. Stelle von 13549586 ist 9
Mhhhh, ich seh die vier an vierter Stelle....

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: So 19.11.06 19:08 
Die Stellen werden von hinten gezählt, wie immer ;)
ausblenden Quelltext
1:
2:
4. Stelle von 13549586 ist 9
              87654321

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: So 19.11.06 19:12 
user profile iconMartok hat folgendes geschrieben:
Die Stellen werden von hinten gezählt, wie immer ;)
ausblenden Quelltext
1:
2:
4. Stelle von 13549586 ist 9
              87654321
Sorry, da hab ich vor lauter Bäumen den Wald nicht gesehen. Hab in der zweiten Zeile geschaut und da hat es nach meiner Logik gestimmt.

Oh man, ich geh jetzt schlafen. Danke!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.