hedgewars/uFloat.pas
branchtransitional_engine
changeset 15900 128ace913837
parent 15896 d2dafe1b25f5
equal deleted inserted replaced
15899:73cdc306888f 15900:128ace913837
    54     1: (QWordValue : QWord);
    54     1: (QWordValue : QWord);
    55     end;
    55     end;
    56 {$ENDIF}
    56 {$ENDIF}
    57 
    57 
    58 // Returns an hwFloat that represents the value of integer parameter i
    58 // Returns an hwFloat that represents the value of integer parameter i
    59 function int2hwFloat (const i: LongInt) : hwFloat; inline;
    59 function int2hwFloat (const i: LongInt) : hwFloat; 
    60 function hwFloat2Float (const i: hwFloat) : extended; inline;
    60 function hwFloat2Float (const i: hwFloat) : extended; 
    61 
    61 
    62 // The implemented operators
    62 // The implemented operators
    63 
    63 
    64 operator = (const z1, z2: hwFloat) z : boolean; inline;
    64 operator = (const z1, z2: hwFloat) z : boolean; 
    65 {$IFDEF PAS2C}
    65 {$IFDEF PAS2C}
    66 operator <> (const z1, z2: hwFloat) z : boolean; inline;
    66 operator <> (const z1, z2: hwFloat) z : boolean; 
    67 {$ENDIF}
    67 {$ENDIF}
    68 operator + (const z1, z2: hwFloat) z : hwFloat; inline;
    68 operator + (const z1, z2: hwFloat) z : hwFloat; 
    69 operator - (const z1, z2: hwFloat) z : hwFloat; inline;
    69 operator - (const z1, z2: hwFloat) z : hwFloat; 
    70 operator - (const z1: hwFloat) z : hwFloat; inline;
    70 operator - (const z1: hwFloat) z : hwFloat; 
    71 
    71 
    72 operator * (const z1, z2: hwFloat) z : hwFloat; inline;
    72 operator * (const z1, z2: hwFloat) z : hwFloat; 
    73 operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline;
    73 operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; 
    74 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline;
    74 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; 
    75 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline;
    75 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; 
    76 
    76 
    77 operator < (const z1, z2: hwFloat) b : boolean; inline;
    77 operator < (const z1, z2: hwFloat) b : boolean; 
    78 operator > (const z1, z2: hwFloat) b : boolean; inline;
    78 operator > (const z1, z2: hwFloat) b : boolean; 
    79 
    79 
    80 
    80 
    81 // Various functions for hwFloat (some are inlined in the resulting code for better performance)
    81 // Various functions for hwFloat (some are inlined in the resulting code for better performance)
    82 
    82 
    83 function cstr(const z: hwFloat): shortstring; // Returns a shortstring representations of the hwFloat.
    83 function cstr(const z: hwFloat): shortstring; // Returns a shortstring representations of the hwFloat.
    84 function hwRound(const t: hwFloat): LongInt; inline; // Does NOT really round but returns the integer representation of the hwFloat without fractional digits. (-_0_9 -> -0, _1_5 -> _1)
    84 function hwRound(const t: hwFloat): LongInt;  // Does NOT really round but returns the integer representation of the hwFloat without fractional digits. (-_0_9 -> -0, _1_5 -> _1)
    85 function hwAbs(const t: hwFloat): hwFloat; inline; // Returns the value of t with positive sign.
    85 function hwAbs(const t: hwFloat): hwFloat;  // Returns the value of t with positive sign.
    86 function hwSqr(const t: hwFloat): hwFloat; inline; // Returns the square value of parameter t.
    86 function hwSqr(const t: hwFloat): hwFloat;  // Returns the square value of parameter t.
    87 function hwSqrt1(const t: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t.
    87 function hwSqrt1(const t: hwFloat): hwFloat;  // Returns the the positive square root of parameter t.
    88 function hwSqrt(const x: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t.
    88 function hwSqrt(const x: hwFloat): hwFloat;  // Returns the the positive square root of parameter t.
    89 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.
    89 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.
    90 function DistanceI(const dx, dy: LongInt): hwFloat; // Same as above for integer parameters.
    90 function DistanceI(const dx, dy: LongInt): hwFloat; // Same as above for integer parameters.
    91 function AngleSin(const Angle: Longword): hwFloat;
    91 function AngleSin(const Angle: Longword): hwFloat;
    92 function AngleCos(const Angle: Longword): hwFloat;
    92 function AngleCos(const Angle: Longword): hwFloat;
    93 function vector2Angle(const x, y: hwFloat): LongInt;
    93 function vector2Angle(const x, y: hwFloat): LongInt;
    94 function SignAs(const num, signum: hwFloat): hwFloat; inline; // Returns an hwFloat with the value of parameter num and the sign of signum.
    94 function SignAs(const num, signum: hwFloat): hwFloat;  // Returns an hwFloat with the value of parameter num and the sign of signum.
    95 function hwSign(r: hwFloat): LongInt; inline; // Returns an integer with value 1 and sign of parameter r.
    95 function hwSign(r: hwFloat): LongInt;  // Returns an integer with value 1 and sign of parameter r.
    96 function hwSignf(r: real): LongInt; inline; // Returns an integer with value 1 and sign of parameter r.
    96 function hwSignf(r: real): LongInt;  // Returns an integer with value 1 and sign of parameter r.
    97 function isZero(const z: hwFloat): boolean; inline;
    97 function isZero(const z: hwFloat): boolean; 
    98 
    98 
    99 {$WARNINGS OFF}
    99 {$WARNINGS OFF}
   100 // some hwFloat constants
   100 // some hwFloat constants
   101 const  _1div1024: hwFloat = (isNegative: false; QWordValue:     4194304);
   101 const  _1div1024: hwFloat = (isNegative: false; QWordValue:     4194304);
   102       _1div10000: hwFloat = (isNegative: false; QWordValue:      429496);
   102       _1div10000: hwFloat = (isNegative: false; QWordValue:      429496);
   193 
   193 
   194 implementation
   194 implementation
   195 uses uSinTable;
   195 uses uSinTable;
   196 
   196 
   197 
   197 
   198 function int2hwFloat (const i: LongInt) : hwFloat; inline;
   198 function int2hwFloat (const i: LongInt) : hwFloat; 
   199 begin
   199 begin
   200 int2hwFloat.isNegative:= i < 0;
   200 int2hwFloat.isNegative:= i < 0;
   201 int2hwFloat.Round:= abs(i);
   201 int2hwFloat.Round:= abs(i);
   202 int2hwFloat.Frac:= 0
   202 int2hwFloat.Frac:= 0
   203 end;
   203 end;
   204 
   204 
   205 function hwFloat2Float (const i: hwFloat) : extended; inline;
   205 function hwFloat2Float (const i: hwFloat) : extended; 
   206 begin
   206 begin
   207 hwFloat2Float:= i.Frac / $100000000 + i.Round;
   207 hwFloat2Float:= i.Frac / $100000000 + i.Round;
   208 if i.isNegative then
   208 if i.isNegative then
   209     hwFloat2Float:= -hwFloat2Float;
   209     hwFloat2Float:= -hwFloat2Float;
   210 end;
   210 end;
   211 
   211 
   212 operator = (const z1, z2: hwFloat) z : boolean; inline;
   212 operator = (const z1, z2: hwFloat) z : boolean; 
   213 begin
   213 begin
   214     z:= (z1.isNegative = z2.isNegative) and (z1.QWordValue = z2.QWordValue);
   214     z:= (z1.isNegative = z2.isNegative) and (z1.QWordValue = z2.QWordValue);
   215 end;
   215 end;
   216 
   216 
   217 {$IFDEF PAS2C}
   217 {$IFDEF PAS2C}
   218 operator <> (const z1, z2: hwFloat) z : boolean; inline;
   218 operator <> (const z1, z2: hwFloat) z : boolean; 
   219 begin
   219 begin
   220     z:= (z1.isNegative <> z2.isNegative) or (z1.QWordValue <> z2.QWordValue);
   220     z:= (z1.isNegative <> z2.isNegative) or (z1.QWordValue <> z2.QWordValue);
   221 end;
   221 end;
   222 {$ENDIF}
   222 {$ENDIF}
   223 
   223 
   224 operator + (const z1, z2: hwFloat) z : hwFloat; inline;
   224 operator + (const z1, z2: hwFloat) z : hwFloat; 
   225 begin
   225 begin
   226 if z1.isNegative = z2.isNegative then
   226 if z1.isNegative = z2.isNegative then
   227     begin
   227     begin
   228     z.isNegative:= z1.isNegative;
   228     z.isNegative:= z1.isNegative;
   229     z.QWordValue:= z1.QWordValue + z2.QWordValue
   229     z.QWordValue:= z1.QWordValue + z2.QWordValue
   239         z.isNegative:= z2.isNegative;
   239         z.isNegative:= z2.isNegative;
   240         z.QWordValue:= z2.QWordValue - z1.QWordValue
   240         z.QWordValue:= z2.QWordValue - z1.QWordValue
   241         end
   241         end
   242 end;
   242 end;
   243 
   243 
   244 operator - (const z1, z2: hwFloat) z : hwFloat; inline;
   244 operator - (const z1, z2: hwFloat) z : hwFloat; 
   245 begin
   245 begin
   246 if z1.isNegative = z2.isNegative then
   246 if z1.isNegative = z2.isNegative then
   247     if z1.QWordValue > z2.QWordValue then
   247     if z1.QWordValue > z2.QWordValue then
   248         begin
   248         begin
   249         z.isNegative:= z1.isNegative;
   249         z.isNegative:= z1.isNegative;
   259     z.isNegative:= z1.isNegative;
   259     z.isNegative:= z1.isNegative;
   260     z.QWordValue:= z1.QWordValue + z2.QWordValue
   260     z.QWordValue:= z1.QWordValue + z2.QWordValue
   261     end
   261     end
   262 end;
   262 end;
   263 
   263 
   264 function isZero(const z: hwFloat): boolean; inline;
   264 function isZero(const z: hwFloat): boolean; 
   265 begin
   265 begin
   266 isZero := z.QWordValue = 0;
   266 isZero := z.QWordValue = 0;
   267 end;
   267 end;
   268 
   268 
   269 operator < (const z1, z2: hwFloat) b : boolean; inline;
   269 operator < (const z1, z2: hwFloat) b : boolean; 
   270 begin
   270 begin
   271 if z1.isNegative xor z2.isNegative then
   271 if z1.isNegative xor z2.isNegative then
   272     b:= z1.isNegative
   272     b:= z1.isNegative
   273 else
   273 else
   274     if z1.QWordValue = z2.QWordValue then
   274     if z1.QWordValue = z2.QWordValue then
   275         b:= false
   275         b:= false
   276     else
   276     else
   277         b:= (z2.QWordValue < z1.QWordValue) = z1.isNegative
   277         b:= (z2.QWordValue < z1.QWordValue) = z1.isNegative
   278 end;
   278 end;
   279 
   279 
   280 operator > (const z1, z2: hwFloat) b : boolean; inline;
   280 operator > (const z1, z2: hwFloat) b : boolean; 
   281 begin
   281 begin
   282 if z1.isNegative xor z2.isNegative then
   282 if z1.isNegative xor z2.isNegative then
   283     b:= z2.isNegative
   283     b:= z2.isNegative
   284 else
   284 else
   285     if z1.QWordValue = z2.QWordValue then
   285     if z1.QWordValue = z2.QWordValue then
   286         b:= false
   286         b:= false
   287     else
   287     else
   288         b:= (z1.QWordValue > z2.QWordValue) <> z2.isNegative
   288         b:= (z1.QWordValue > z2.QWordValue) <> z2.isNegative
   289 end;
   289 end;
   290 
   290 
   291 operator - (const z1: hwFloat) z : hwFloat; inline;
   291 operator - (const z1: hwFloat) z : hwFloat; 
   292 begin
   292 begin
   293     z:= z1;
   293     z:= z1;
   294     z.isNegative:= not z.isNegative
   294     z.isNegative:= not z.isNegative
   295 end;
   295 end;
   296 
   296 
   297 
   297 
   298 operator * (const z1, z2: hwFloat) z : hwFloat; inline;
   298 operator * (const z1, z2: hwFloat) z : hwFloat; 
   299 begin
   299 begin
   300     z.isNegative:= z1.isNegative xor z2.isNegative;
   300     z.isNegative:= z1.isNegative xor z2.isNegative;
   301     
   301     
   302     if (z1.Round = 0) and (z2.Round = 0) then
   302     if (z1.Round = 0) and (z2.Round = 0) then
   303         begin
   303         begin
   308         z.QWordValue:= QWord(z1.Round) * z2.Frac + QWord(z1.Frac) * z2.Round + ((QWord(z1.Frac) * z2.Frac) shr 32);
   308         z.QWordValue:= QWord(z1.Round) * z2.Frac + QWord(z1.Frac) * z2.Round + ((QWord(z1.Frac) * z2.Frac) shr 32);
   309         z.Round:= z.Round + QWord(z1.Round) * z2.Round;
   309         z.Round:= z.Round + QWord(z1.Round) * z2.Round;
   310     end
   310     end
   311 end;
   311 end;
   312 
   312 
   313 operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline;
   313 operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; 
   314 begin
   314 begin
   315     z.isNegative:= z1.isNegative xor (z2 < 0);
   315     z.isNegative:= z1.isNegative xor (z2 < 0);
   316     z.QWordValue:= z1.QWordValue * abs(z2)
   316     z.QWordValue:= z1.QWordValue * abs(z2)
   317 end;
   317 end;
   318 
   318 
   319 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline;
   319 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; 
   320 var t: QWord;
   320 var t: QWord;
   321 begin
   321 begin
   322     z.isNegative:= z1.isNegative xor z2.isNegative;
   322     z.isNegative:= z1.isNegative xor z2.isNegative;
   323     z.Round:= z1.QWordValue div z2.QWordValue;
   323     z.Round:= z1.QWordValue div z2.QWordValue;
   324     t:= z1.QWordValue - z2.QWordValue * z.Round;
   324     t:= z1.QWordValue - z2.QWordValue * z.Round;
   335         if z2.Round > 0 then
   335         if z2.Round > 0 then
   336             inc(z.QWordValue, t div z2.Round);
   336             inc(z.QWordValue, t div z2.Round);
   337         end
   337         end
   338 end;
   338 end;
   339 
   339 
   340 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline;
   340 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; 
   341 begin
   341 begin
   342     z.isNegative:= z1.isNegative xor (z2 < 0);
   342     z.isNegative:= z1.isNegative xor (z2 < 0);
   343     z.QWordValue:= z1.QWordValue div abs(z2)
   343     z.QWordValue:= z1.QWordValue div abs(z2)
   344 end;
   344 end;
   345 
   345 
   369 begin
   369 begin
   370     hwAbs:= t;
   370     hwAbs:= t;
   371     hwAbs.isNegative:= false
   371     hwAbs.isNegative:= false
   372 end;
   372 end;
   373 
   373 
   374 function hwSqr(const t: hwFloat): hwFloat; inline;
   374 function hwSqr(const t: hwFloat): hwFloat; 
   375 begin
   375 begin
   376     hwSqr.isNegative:= false;
   376     hwSqr.isNegative:= false;
   377     hwSqr.QWordValue:= ((QWord(t.Round) * t.Round) shl 32) + QWord(t.Round) * t.Frac * 2 + ((QWord(t.Frac) * t.Frac) shr 32);
   377     hwSqr.QWordValue:= ((QWord(t.Round) * t.Round) shl 32) + QWord(t.Round) * t.Frac * 2 + ((QWord(t.Frac) * t.Frac) shr 32);
   378 end;
   378 end;
   379 
   379