Wieso bekomme ich hier einen arithmetischen Überlauf?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1875
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Wieso bekomme ich hier einen arithmetischen Überlauf?

Beitrag von fliegermichl »

Code: Alles auswählen

program Project1;
var c, l, h : integer;
begin
 l := 2;
 h := 1;
 c := l + ((h-l) shr 1);
end.
Der Code kommt In einer Quicksortroutine zum Einsatz und erzeugt einen arithmetischen Überlauf. Ich verstehe aber nicht weshalb?
Kann mal jemand meinen Fuß von der Leitung nehmen bitte.

Benutzeravatar
Zvoni
Beiträge: 789
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 11 Pro (Laz4.3/FPC3.2.3)
CPU-Target: 64Bit
Wohnort: BW

Re: Wieso bekomme ich hier einen arithmetischen Überlauf?

Beitrag von Zvoni »

fliegermichl hat geschrieben: Mi 11. Nov 2026, 12:05

Code: Alles auswählen

program Project1;
var c, l, h : integer;
begin
 l := 2;
 h := 1;
 c := l + ((h-l) shr 1);
end.
Der Code kommt In einer Quicksortroutine zum Einsatz und erzeugt einen arithmetischen Überlauf. Ich verstehe aber nicht weshalb?
Kann mal jemand meinen Fuß von der Leitung nehmen bitte.
Yepp. Bekomme einen Range-Check
Anscheinend mag er kein "0 shr 1"

ich habe gesehen, dass es ein Thema gibt, wenn es sich um negative integers handelt (links vom shr).
ein "shr 1" ignoriert das Vorzeichen und haut ne "0" ins oberste Bit, was das Ergebnis definitiv positiv macht, ggfs. aber dann astronomisch
Was aber bei deinen Beispielwerten jetzt keinen Sinn ergibt.

Ansonsten die Alternative "div 2" nutzen

führ mal das aus:

Code: Alles auswählen

+
program Project1;
{$mode ObjFPC}{$H+}
var l, h : Int64;
  c,t:Int64;
begin
 l := 2;
 h := 1;

 t:=(h-l) shr 1;
 Writeln('t=',t);
 c := l + t;
 writeln('c=',c);
 Readln;
end.
und schau dir mal t und c an.....

EDIT:
Hab noch was gefunden.
https://forum.lazarus.freepascal.org/in ... #msg278650
The result is undefined if the right operand of a shift expression is negative or if the right operand is greater than or equal to the number of bits in the (promoted) left operand.
Auf Deutsch: Undefiniertes Verhalten, falls rechts vom shr mehr oder gleich viele Bits stehen, wie links verschoben werden sollen.
Und in deinem Beispiel-Code willst du ja "0 shr 1" machen....
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1875
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Wieso bekomme ich hier einen arithmetischen Überlauf?

Beitrag von fliegermichl »

Danke. Ich denke auch, daß es durch das stumpfe rechts shiften von links her mit 0 aufgefüllt wird und dadurch ein sehr großer Integer Wert entsteht (MaxInt) und zu dem 2 hinzuaddiert sprengt dann den Rahmen.

Ich hab es jetzt auf div 2 umgestellt und dann klappt es.

Benutzeravatar
Zvoni
Beiträge: 789
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 11 Pro (Laz4.3/FPC3.2.3)
CPU-Target: 64Bit
Wohnort: BW

Re: Wieso bekomme ich hier einen arithmetischen Überlauf?

Beitrag von Zvoni »

fliegermichl hat geschrieben: Mi 11. Nov 2026, 14:28 Danke. Ich denke auch, daß es durch das stumpfe rechts shiften von links her mit 0 aufgefüllt wird und dadurch ein sehr großer Integer Wert entsteht (MaxInt) und zu dem 2 hinzuaddiert sprengt dann den Rahmen.

Ich hab es jetzt auf div 2 umgestellt und dann klappt es.
x shr 1 ist halt sehr schnell

Vielleicht als Bedingung?
Kommt halt drauf an, was häufiger vorkommt
Im Prinzip sowas

Code: Alles auswählen

program Project1;
var c, l, h : integer;
begin
 l := 2;
 h := 1;
 If (h-l)>1 Then  
    c := l + ((h-l) shr 1)
 Else
    c := l + ((h-l) div 2);
end.
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1875
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Wieso bekomme ich hier einen arithmetischen Überlauf?

Beitrag von fliegermichl »

Ich denke, dass der Vergleich + shr vermutlich nicht viel schneller sein wird als das div. Zumal der Quicksort Algorithmus ja recht effizient ist und es insgesamt gar nicht so viele Vergleiche braucht.

Antworten