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 |
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; |