Skip to content

Commit 0846cb8

Browse files
committed
Clipper.Core.pas - fixed a bug in MultiplyUInt64 function
1 parent 9831776 commit 0846cb8

File tree

1 file changed

+35
-21
lines changed

1 file changed

+35
-21
lines changed

Delphi/Clipper2Lib/Clipper.Core.pas

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
(*******************************************************************************
44
* Author : Angus Johnson *
5-
* Date : 7 October 2025 *
5+
* Date : 10 October 2025 *
66
* Website : https://www.angusj.com *
77
* Copyright : Angus Johnson 2010-2024 *
88
* Purpose : Core Clipper Library module *
@@ -185,6 +185,7 @@ function DotProduct(const vec1, vec2: TPointD): double; overload;
185185
{$IFDEF INLINING} inline; {$ENDIF}
186186
function DotProduct(const pt1, pt2, pt3: TPoint64): double; overload;
187187
{$IFDEF INLINING} inline; {$ENDIF}
188+
function DotProductSign(const pt1, pt2, pt3: TPoint64): integer;
188189

189190
function DistanceSqr(const pt1, pt2: TPoint64): double; overload;
190191
{$IFDEF INLINING} inline; {$ENDIF}
@@ -1968,35 +1969,20 @@ function MultiplyUInt64(a, b: UInt64): TUInt128; // #834, #835
19681969
var
19691970
x1, x2, x3: UInt64;
19701971
begin
1971-
if (a = 0) or (b = 0) then
1972-
begin
1973-
Result.lo64 := 0;
1974-
Result.hi64 := 0;
1975-
Exit;
1976-
end;
19771972
x1 := (a and $FFFFFFFF) * (b and $FFFFFFFF);
19781973
x2 := (a shr 32) * (b and $FFFFFFFF) + (x1 shr 32);
19791974
x3 := (a and $FFFFFFFF) * (b shr 32) + (x2 and $FFFFFFFF);
19801975
Result.lo64 := ((x3 and $FFFFFFFF) shl 32) or (x1 and $FFFFFFFF);
1981-
Result.hi64 := hi(a shr 32) * (b shr 32) + (x2 shr 32) + (x3 shr 32);
1982-
end;
1983-
//------------------------------------------------------------------------------
1984-
1985-
function Int128Add(const Int1, Int2: TUInt128): TUInt128;
1986-
{$IFDEF INLINING} inline; {$ENDIF}
1987-
begin
1988-
Result.Lo64 := Int1.Lo64 + Int2.Lo64;
1989-
Result.Hi64 := Int1.Hi64 + Int2.Hi64;
1990-
if Result.Lo64 < Int1.Lo64 then Inc(Result.Hi64);
1976+
Result.hi64 := (a shr 32) * (b shr 32) + (x2 shr 32) + (x3 shr 32);
19911977
end;
19921978
//------------------------------------------------------------------------------
19931979

1994-
function Int128Sub(const Int1, Int2: TUInt128): TUInt128;
1980+
function Int128GreaterThan(const Int1, Int2: TUInt128): Boolean;
19951981
{$IFDEF INLINING} inline; {$ENDIF}
19961982
begin
1997-
Result.Lo64 := Int1.Lo64 - Int2.Lo64;
1998-
Result.Hi64 := Int1.Hi64 - Int2.Hi64;
1999-
if Result.Lo64 > Int1.Lo64 then Dec(Result.Hi64);
1983+
if Int1.Hi64 <> Int2.Hi64 then
1984+
Result := Int1.Hi64 > Int2.Hi64 else
1985+
Result := Int1.Lo64 > Int2.Lo64;
20001986
end;
20011987
//------------------------------------------------------------------------------
20021988
{$OVERFLOWCHECKS ON}
@@ -2037,6 +2023,34 @@ function DotProduct(const pt1, pt2, pt3: TPoint64): double;
20372023
end;
20382024
//------------------------------------------------------------------------------
20392025

2026+
function DotProductSign(const pt1, pt2, pt3: TPoint64): integer;
2027+
var
2028+
a,b,c,d : Int64;
2029+
signAB, signCD: integer;
2030+
ab, cd: TUInt128;
2031+
begin
2032+
a := pt2.X - pt1.X;
2033+
b := pt3.X - pt2.X;
2034+
c := pt2.Y - pt1.Y;
2035+
d := pt3.Y - pt2.Y;
2036+
2037+
signAB := TriSign(a) * TriSign(b);
2038+
signCD := TriSign(c) * TriSign(d);
2039+
2040+
if signAB = signCD then
2041+
begin
2042+
Result := signAB;
2043+
end else
2044+
begin
2045+
ab := MultiplyUInt64(Abs(a), Abs(b));
2046+
cd := MultiplyUInt64(Abs(c), Abs(d));
2047+
if Int128GreaterThan(ab, cd) then
2048+
Result := signAB else
2049+
Result := signCD;
2050+
end;
2051+
end;
2052+
//------------------------------------------------------------------------------
2053+
20402054
function ProductsAreEqual(a, b, c, d: Int64): Boolean;
20412055
{$IFDEF INLINING} inline; {$ENDIF}
20422056
var

0 commit comments

Comments
 (0)