diff -r 6ea838b8dcd5 -r 13ac59499066 hedgewars/uFloat.pas --- a/hedgewars/uFloat.pas Sat Apr 20 02:17:53 2013 +0200 +++ b/hedgewars/uFloat.pas Sat Apr 20 02:20:15 2013 +0200 @@ -84,7 +84,8 @@ function hwAbs(const t: hwFloat): hwFloat; inline; // Returns the value of t with positive sign. function hwSqr(const t: hwFloat): hwFloat; inline; // Returns the square value of parameter t. function hwPow(const t: hwFloat; p: LongWord): hwFloat; inline; // Returns the power of the value -function hwSqrt(const t: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t. +function hwSqrt1(const t: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t. +function hwSqrt(const x: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t. function Distance(const dx, dy: hwFloat): hwFloat; // Returns the distance between two points in 2-dimensional space, of which the parameters are the horizontal and vertical distance. function DistanceI(const dx, dy: LongInt): hwFloat; // Same as above for integer parameters. function AngleSin(const Angle: Longword): hwFloat; @@ -264,7 +265,7 @@ end end; -function isZero(const z: hwFloat): boolean; inline; +function isZero(const z: hwFloat): boolean; inline; begin isZero := z.QWordValue = 0; end; @@ -277,7 +278,7 @@ if z1.QWordValue = z2.QWordValue then b:= false else - b:= not((z1.QWordValue = z2.QWordValue) or ((z2.QWordValue < z1.QWordValue) <> z1.isNegative)) + b:= (z2.QWordValue < z1.QWordValue) = z1.isNegative end; operator > (const z1, z2: hwFloat) b : boolean; inline; @@ -312,24 +313,23 @@ end; operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline; -var t: hwFloat; +var t: QWord; begin z.isNegative:= z1.isNegative xor z2.isNegative; z.Round:= z1.QWordValue div z2.QWordValue; -t:= z1 - z2 * z.Round; -if t.QWordValue = 0 then - z.Frac:= 0 -else +t:= z1.QWordValue - z2.QWordValue * z.Round; +z.Frac:= 0; + +if t <> 0 then begin - while ((t.QWordValue and $8000000000000000) = 0) and ((z2.QWordValue and $8000000000000000) = 0) do + while ((t and $FF00000000000000) = 0) and ((z2.QWordValue and $FF00000000000000) = 0) do begin - t.QWordValue:= t.QWordValue shl 1; - z2.QWordValue:= z2.QWordValue shl 1 + t:= t shl 8; + z2.QWordValue:= z2.QWordValue shl 8 end; + if z2.Round > 0 then - z.Frac:= (t.QWordValue) div (z2.Round) - else - z.Frac:= 0 + inc(z.QWordValue, t div z2.Round); end end; @@ -385,14 +385,14 @@ end end; -function hwSqrt(const t: hwFloat): hwFloat; +function hwSqrt1(const t: hwFloat): hwFloat; const pwr = 8; // even value, feel free to adjust rThreshold = 1 shl (pwr + 32); lThreshold = 1 shl (pwr div 2 + 32); var l, r: QWord; c: hwFloat; begin -hwSqrt.isNegative:= false; +hwSqrt1.isNegative:= false; if t.Round = 0 then begin @@ -425,12 +425,47 @@ l:= c.QWordValue until r - l <= 1; -hwSqrt.QWordValue:= l +hwSqrt1.QWordValue:= l end; -function Distance(const dx, dy: hwFloat): hwFloat; +function hwSqrt(const x: hwFloat): hwFloat; +var r, t, s, q: QWord; + i: integer; begin -Distance:= hwSqrt(hwSqr(dx) + hwSqr(dy)) +hwSqrt.isNegative:= false; + +t:= $4000000000000000; +r:= 0; +q:= x.QWordValue; + +for i:= 0 to 31 do + begin + s:= r + t; + r:= r shr 1; + if s <= q then + begin + dec(q, s); + inc(r, t); + end; + t:= t shr 2; + end; + +hwSqrt.QWordValue:= r shl 16 +end; + + + +function Distance(const dx, dy: hwFloat): hwFloat; +var r: QWord; +begin +r:= dx.QWordValue or dy.QWordValue; + +if r < $10000 then + begin + Distance.QWordValue:= r; + Distance.isNegative:= false + end else + Distance:= hwSqrt(hwSqr(dx) + hwSqr(dy)) end; function DistanceI(const dx, dy: LongInt): hwFloat;