diff -r 56d2f2d5aad8 -r 4feced261c68 hedgewars/uFloat.pas --- a/hedgewars/uFloat.pas Sun Jan 19 00:18:28 2014 +0400 +++ b/hedgewars/uFloat.pas Tue Jan 21 22:38:13 2014 +0100 @@ -39,7 +39,6 @@ *) interface -{$IFDEF FPC} {$IFDEF ENDIAN_LITTLE} type hwFloat = record isNegative: boolean; @@ -63,7 +62,9 @@ // The implemented operators operator = (const z1, z2: hwFloat) z : boolean; inline; - +{$IFDEF PAS2C} +operator <> (const z1, z2: hwFloat) z : boolean; inline; +{$ENDIF} operator + (const z1, z2: hwFloat) z : hwFloat; inline; operator - (const z1, z2: hwFloat) z : hwFloat; inline; operator - (const z1: hwFloat) z : hwFloat; inline; @@ -95,14 +96,9 @@ function hwSign(r: hwFloat): LongInt; inline; // Returns an integer with value 1 and sign of parameter r. function hwSignf(r: real): LongInt; inline; // Returns an integer with value 1 and sign of parameter r. function isZero(const z: hwFloat): boolean; inline; -{$IFDEF FPC} -{$J-} -{$ENDIF} + {$WARNINGS OFF} - - // some hwFloat constants - const _1div1024: hwFloat = (isNegative: false; QWordValue: 4194304); _1div10000: hwFloat = (isNegative: false; QWordValue: 429496); _1div50000: hwFloat = (isNegative: false; QWordValue: 85899); @@ -150,20 +146,20 @@ _0_999: hwFloat = (isNegative: false; QWordValue: 4290672328); _0: hwFloat = (isNegative: false; QWordValue: 0); _1: hwFloat = (isNegative: false; QWordValue: 4294967296); - _1_2: hwFloat = (isNegative: false; QWordValue: 1288490189*4); + _1_2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 6 div 5 + 1); _1_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3 div 2); _1_6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 8 div 5); _1_9: hwFloat = (isNegative: false; QWordValue: 8160437862); _2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 2); _2_4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12 div 5); _3: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3); - _3_2: hwFloat = (isNegative: false; QWordValue: 3435973837*4); + _3_2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 16 div 5); _PI: hwFloat = (isNegative: false; QWordValue: 13493037704); _4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 4); _4_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 9 div 2); _5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 5); _6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 6); - _6_4: hwFloat = (isNegative: false; QWordValue: 3435973837 * 8); + _6_4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 32 div 5); _7: hwFloat = (isNegative: false; QWordValue: 4294967296 * 7); _10: hwFloat = (isNegative: false; QWordValue: 4294967296 * 10); _12: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12); @@ -194,18 +190,11 @@ cLittle: hwFloat = (isNegative: false; QWordValue: 1); cHHKick: hwFloat = (isNegative: false; QWordValue: 42949673); // _0_01 {$WARNINGS ON} -{$ENDIF} - -{$IFNDEF FPC} -type hwFloat = Extended; -{$ENDIF} implementation uses uSinTable; -{$IFDEF FPC} - function int2hwFloat (const i: LongInt) : hwFloat; inline; begin int2hwFloat.isNegative:= i < 0; @@ -225,6 +214,13 @@ z:= (z1.isNegative = z2.isNegative) and (z1.QWordValue = z2.QWordValue); end; +{$IFDEF PAS2C} +operator <> (const z1, z2: hwFloat) z : boolean; inline; +begin + z:= (z1.isNegative <> z2.isNegative) or (z1.QWordValue <> z2.QWordValue); +end; +{$ENDIF} + operator + (const z1, z2: hwFloat) z : hwFloat; inline; begin if z1.isNegative = z2.isNegative then @@ -294,95 +290,95 @@ operator - (const z1: hwFloat) z : hwFloat; inline; begin -z:= z1; -z.isNegative:= not z.isNegative + z:= z1; + z.isNegative:= not z.isNegative end; operator * (const z1, z2: hwFloat) z : hwFloat; inline; begin -z.isNegative:= z1.isNegative xor z2.isNegative; -z.QWordValue:= QWord(z1.Round) * z2.Frac + QWord(z1.Frac) * z2.Round + ((QWord(z1.Frac) * z2.Frac) shr 32); -z.Round:= z.Round + QWord(z1.Round) * z2.Round; + z.isNegative:= z1.isNegative xor z2.isNegative; + z.QWordValue:= QWord(z1.Round) * z2.Frac + QWord(z1.Frac) * z2.Round + ((QWord(z1.Frac) * z2.Frac) shr 32); + z.Round:= z.Round + QWord(z1.Round) * z2.Round; end; operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; begin -z.isNegative:= z1.isNegative xor (z2 < 0); -z.QWordValue:= z1.QWordValue * abs(z2) + z.isNegative:= z1.isNegative xor (z2 < 0); + z.QWordValue:= z1.QWordValue * abs(z2) end; operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline; var t: QWord; begin -z.isNegative:= z1.isNegative xor z2.isNegative; -z.Round:= z1.QWordValue div z2.QWordValue; -t:= z1.QWordValue - z2.QWordValue * z.Round; -z.Frac:= 0; + z.isNegative:= z1.isNegative xor z2.isNegative; + z.Round:= z1.QWordValue div z2.QWordValue; + t:= z1.QWordValue - z2.QWordValue * z.Round; + z.Frac:= 0; -if t <> 0 then - begin - while ((t and $FF00000000000000) = 0) and ((z2.QWordValue and $FF00000000000000) = 0) do + if t <> 0 then begin - t:= t shl 8; - z2.QWordValue:= z2.QWordValue shl 8 - end; + while ((t and $FF00000000000000) = 0) and ((z2.QWordValue and $FF00000000000000) = 0) do + begin + t:= t shl 8; + z2.QWordValue:= z2.QWordValue shl 8 + end; - if z2.Round > 0 then - inc(z.QWordValue, t div z2.Round); - end + if z2.Round > 0 then + inc(z.QWordValue, t div z2.Round); + end end; operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; begin -z.isNegative:= z1.isNegative xor (z2 < 0); -z.QWordValue:= z1.QWordValue div abs(z2) + z.isNegative:= z1.isNegative xor (z2 < 0); + z.QWordValue:= z1.QWordValue div abs(z2) end; function cstr(const z: hwFloat): shortstring; var tmpstr: shortstring; begin -str(z.Round, cstr); -if z.Frac <> 0 then - begin - str(z.Frac / $100000000, tmpstr); - delete(tmpstr, 1, 2); - cstr:= cstr + '.' + copy(tmpstr, 1, 10) - end; -if z.isNegative then - cstr:= '-' + cstr + str(z.Round, cstr); + if z.Frac <> 0 then + begin + str(z.Frac / $100000000, tmpstr); + delete(tmpstr, 1, 2); + cstr:= cstr + '.' + copy(tmpstr, 1, 10) + end; + if z.isNegative then + cstr:= '-' + cstr end; function hwRound(const t: hwFloat): LongInt; begin -if t.isNegative then - hwRound:= -(t.Round and $7FFFFFFF) -else - hwRound:= t.Round and $7FFFFFFF + if t.isNegative then + hwRound:= -(t.Round and $7FFFFFFF) + else + hwRound:= t.Round and $7FFFFFFF end; function hwAbs(const t: hwFloat): hwFloat; begin -hwAbs:= t; -hwAbs.isNegative:= false + hwAbs:= t; + hwAbs.isNegative:= false end; function hwSqr(const t: hwFloat): hwFloat; inline; begin -hwSqr.isNegative:= false; -hwSqr.QWordValue:= ((QWord(t.Round) * t.Round) shl 32) + QWord(t.Round) * t.Frac * 2 + ((QWord(t.Frac) * t.Frac) shr 32); + hwSqr.isNegative:= false; + hwSqr.QWordValue:= ((QWord(t.Round) * t.Round) shl 32) + QWord(t.Round) * t.Frac * 2 + ((QWord(t.Frac) * t.Frac) shr 32); end; function hwPow(const t: hwFloat;p: LongWord): hwFloat; begin -hwPow:= t; -if p mod 2 = 0 then hwPow.isNegative:= false; + hwPow:= t; + if p mod 2 = 0 then hwPow.isNegative:= false; -while p > 0 do - begin - hwPow.QWordValue:= QWord(hwPow.Round) * t.Frac + QWord(hwPow.Frac) * t.Round + ((QWord(hwPow.Frac) * t.Frac) shr 32); - dec(p) - end + while p > 0 do + begin + hwPow.QWordValue:= QWord(hwPow.Round) * t.Frac + QWord(hwPow.Frac) * t.Round + ((QWord(hwPow.Frac) * t.Frac) shr 32); + dec(p) + end end; function hwSqrt1(const t: hwFloat): hwFloat; @@ -392,65 +388,67 @@ var l, r: QWord; c: hwFloat; begin -hwSqrt1.isNegative:= false; + hwSqrt1.isNegative:= false; -if t.Round = 0 then - begin - l:= t.QWordValue; - r:= $100000000 - end -else - begin - if t.QWordValue > $FFFFFFFFFFFF then // t.Round > 65535.9999 + if t.Round = 0 then + begin + l:= t.QWordValue; + r:= $100000000 + end + else begin - l:= $10000000000; // 256 - r:= $FFFFFFFFFFFF; // 65535.9999 - end else - if t.QWordValue >= rThreshold then + if t.QWordValue > $FFFFFFFFFFFF then // t.Round > 65535.9999 begin - l:= lThreshold; - r:= $10000000000; // 256 - end else - begin - l:= $100000000; - r:= lThreshold; - end; + l:= $10000000000; // 256 + r:= $FFFFFFFFFFFF; // 65535.9999 + end + else + if t.QWordValue >= rThreshold then + begin + l:= lThreshold; + r:= $10000000000; // 256 + end + else + begin + l:= $100000000; + r:= lThreshold; + end; end; -repeat - c.QWordValue:= (l + r) shr 1; - if hwSqr(c).QWordValue > t.QWordValue then - r:= c.QWordValue - else - l:= c.QWordValue -until r - l <= 1; + repeat + c.QWordValue:= (l + r) shr 1; + if hwSqr(c).QWordValue > t.QWordValue then + r:= c.QWordValue + else + l:= c.QWordValue + until r - l <= 1; -hwSqrt1.QWordValue:= l + hwSqrt1.QWordValue:= l end; function hwSqrt(const x: hwFloat): hwFloat; var r, t, s, q: QWord; i: integer; begin -hwSqrt.isNegative:= false; + hwSqrt.isNegative:= false; -t:= $4000000000000000; -r:= 0; -q:= x.QWordValue; + 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 + for i:= 0 to 31 do begin - dec(q, s); - inc(r, t); + s:= r + t; + r:= r shr 1; + if s <= q then + begin + dec(q, s); + inc(r, t); + end; + t:= t shr 2; end; - t:= t shr 2; - end; -hwSqrt.QWordValue:= r shl 16 + hwSqrt.QWordValue:= r shl 16 end; @@ -458,25 +456,26 @@ function Distance(const dx, dy: hwFloat): hwFloat; var r: QWord; begin -r:= dx.QWordValue or dy.QWordValue; + 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)) + 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; begin -DistanceI:= hwSqrt(int2hwFloat(sqr(dx) + sqr(dy))) + DistanceI:= hwSqrt(int2hwFloat(sqr(dx) + sqr(dy))) end; function SignAs(const num, signum: hwFloat): hwFloat; begin -SignAs.QWordValue:= num.QWordValue; -SignAs.isNegative:= signum.isNegative + SignAs.QWordValue:= num.QWordValue; + SignAs.isNegative:= signum.isNegative end; function hwSign(r: hwFloat): LongInt; @@ -549,6 +548,4 @@ vector2Angle:= c end; -{$ENDIF} - end.