34 0: (Round, Frac: Longword); |
34 0: (Round, Frac: Longword); |
35 1: (QWordValue : QWord); |
35 1: (QWordValue : QWord); |
36 end; |
36 end; |
37 {$endif FPC_LITTLE_ENDIAN} |
37 {$endif FPC_LITTLE_ENDIAN} |
38 |
38 |
39 function int2hwFloat (i: LongInt) : hwFloat; |
39 function int2hwFloat (const i: LongInt) : hwFloat; |
40 |
40 |
41 operator + (z1, z2: hwFloat) z : hwFloat; |
41 operator + (const z1, z2: hwFloat) z : hwFloat; |
42 operator - (z1, z2: hwFloat) z : hwFloat; |
42 operator - (const z1, z2: hwFloat) z : hwFloat; |
43 operator - (z1: hwFloat) z : hwFloat; |
43 operator - (const z1: hwFloat) z : hwFloat; |
44 |
44 |
45 operator * (z1, z2: hwFloat) z : hwFloat; |
45 operator * (const z1, z2: hwFloat) z : hwFloat; |
46 operator * (z1: hwFloat; z2: LongInt) z : hwFloat; |
46 operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; |
47 operator / (z1, z2: hwFloat) z : hwFloat; |
47 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; |
48 operator / (z1: hwFloat; z2: LongInt) z : hwFloat; |
48 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; |
49 |
49 |
50 operator < (z1, z2: hwFloat) b : boolean; |
50 operator < (const z1, z2: hwFloat) b : boolean; |
51 operator > (z1, z2: hwFloat) b : boolean; |
51 operator > (const z1, z2: hwFloat) b : boolean; |
52 |
52 |
53 function cstr(z: hwFloat): string; |
53 function cstr(const z: hwFloat): string; |
54 function hwRound(t: hwFloat): LongInt; |
54 function hwRound(const t: hwFloat): LongInt; |
55 function hwAbs(t: hwFloat): hwFloat; |
55 function hwAbs(const t: hwFloat): hwFloat; |
56 function hwSqr(t: hwFloat): hwFloat; |
56 function hwSqr(const t: hwFloat): hwFloat; |
57 function hwSqrt(t: hwFloat): hwFloat; |
57 function hwSqrt(const t: hwFloat): hwFloat; |
58 function Distance(dx, dy: hwFloat): hwFloat; |
58 function Distance(const dx, dy: hwFloat): hwFloat; |
59 function DistanceI(dx, dy: LongInt): hwFloat; |
59 function DistanceI(const dx, dy: LongInt): hwFloat; |
60 function AngleSin(Angle: Longword): hwFloat; |
60 function AngleSin(const Angle: Longword): hwFloat; |
61 function AngleCos(Angle: Longword): hwFloat; |
61 function AngleCos(const Angle: Longword): hwFloat; |
62 function SignAs(num, signum: hwFloat): hwFloat; |
62 function SignAs(const num, signum: hwFloat): hwFloat; |
63 |
63 |
64 const _1div1024: hwFloat = (isNegative: false; QWordValue: 4194304); |
64 const _1div1024: hwFloat = (isNegative: false; QWordValue: 4194304); |
65 _1div10000: hwFloat = (isNegative: false; QWordValue: 429496); |
65 _1div10000: hwFloat = (isNegative: false; QWordValue: 429496); |
66 _1div50000: hwFloat = (isNegative: false; QWordValue: 85899); |
66 _1div50000: hwFloat = (isNegative: false; QWordValue: 85899); |
67 _1div100000: hwFloat = (isNegative: false; QWordValue: 42950); |
67 _1div100000: hwFloat = (isNegative: false; QWordValue: 42950); |
129 implementation |
129 implementation |
130 uses uConsts; |
130 uses uConsts; |
131 |
131 |
132 {$IFDEF FPC} |
132 {$IFDEF FPC} |
133 |
133 |
134 function int2hwFloat (i: LongInt) : hwFloat; |
134 function int2hwFloat (const i: LongInt) : hwFloat; |
135 begin |
135 begin |
136 int2hwFloat.isNegative:= i < 0; |
136 int2hwFloat.isNegative:= i < 0; |
137 int2hwFloat.Round:= abs(i); |
137 int2hwFloat.Round:= abs(i); |
138 int2hwFloat.Frac:= 0 |
138 int2hwFloat.Frac:= 0 |
139 end; |
139 end; |
140 |
140 |
141 operator + (z1, z2: hwFloat) z : hwFloat; |
141 operator + (const z1, z2: hwFloat) z : hwFloat; |
142 begin |
142 begin |
143 if z1.isNegative = z2.isNegative then |
143 if z1.isNegative = z2.isNegative then |
144 begin |
144 begin |
145 z.isNegative:= z1.isNegative; |
145 z.isNegative:= z1.isNegative; |
146 z.QWordValue:= z1.QWordValue + z2.QWordValue |
146 z.QWordValue:= z1.QWordValue + z2.QWordValue |
173 z.isNegative:= z1.isNegative; |
173 z.isNegative:= z1.isNegative; |
174 z.QWordValue:= z1.QWordValue + z2.QWordValue |
174 z.QWordValue:= z1.QWordValue + z2.QWordValue |
175 end |
175 end |
176 end; |
176 end; |
177 |
177 |
178 operator - (z1: hwFloat) z : hwFloat; |
178 operator - (const z1: hwFloat) z : hwFloat; |
179 begin |
179 begin |
180 z:= z1; |
180 z:= z1; |
181 z.isNegative:= not z.isNegative |
181 z.isNegative:= not z.isNegative |
182 end; |
182 end; |
183 |
183 |
184 |
184 |
185 operator * (z1, z2: hwFloat) z : hwFloat; |
185 operator * (const z1, z2: hwFloat) z : hwFloat; |
186 begin |
186 begin |
187 z.isNegative:= z1.isNegative xor z2.isNegative; |
187 z.isNegative:= z1.isNegative xor z2.isNegative; |
188 z.QWordValue:= QWord(z1.Round) * z2.Frac + |
188 z.QWordValue:= QWord(z1.Round) * z2.Frac + |
189 QWord(z1.Frac) * z2.Round + |
189 QWord(z1.Frac) * z2.Round + |
190 ((QWord(z1.Frac) * z2.Frac) shr 32); |
190 ((QWord(z1.Frac) * z2.Frac) shr 32); |
191 z.Round:= z.Round + QWord(z1.Round) * z2.Round; |
191 z.Round:= z.Round + QWord(z1.Round) * z2.Round; |
192 end; |
192 end; |
193 |
193 |
194 operator * (z1: hwFloat; z2: LongInt) z : hwFloat; |
194 operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; |
195 begin |
195 begin |
196 z.isNegative:= z1.isNegative xor (z2 < 0); |
196 z.isNegative:= z1.isNegative xor (z2 < 0); |
197 z2:= abs(z2); |
197 z.QWordValue:= z1.QWordValue * abs(z2) |
198 z.QWordValue:= z1.QWordValue * z2 |
198 end; |
199 end; |
199 |
200 |
200 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; |
201 operator / (z1, z2: hwFloat) z : hwFloat; |
|
202 var t: hwFloat; |
201 var t: hwFloat; |
203 begin |
202 begin |
204 z.isNegative:= z1.isNegative xor z2.isNegative; |
203 z.isNegative:= z1.isNegative xor z2.isNegative; |
205 z.Round:= z1.QWordValue div z2.QWordValue; |
204 z.Round:= z1.QWordValue div z2.QWordValue; |
206 t:= z1 - z2 * z.Round; |
205 t:= z1 - z2 * z.Round; |
216 end; |
215 end; |
217 z.Frac:= (t.QWordValue) div (z2.Round) |
216 z.Frac:= (t.QWordValue) div (z2.Round) |
218 end |
217 end |
219 end; |
218 end; |
220 |
219 |
221 operator / (z1: hwFloat; z2: LongInt) z : hwFloat; |
220 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; |
222 begin |
221 begin |
223 z.isNegative:= z1.isNegative xor (z2 < 0); |
222 z.isNegative:= z1.isNegative xor (z2 < 0); |
224 z2:= abs(z2); |
223 z.QWordValue:= z1.QWordValue div abs(z2) |
225 z.QWordValue:= z1.QWordValue div z2 |
224 end; |
226 end; |
225 |
227 |
226 operator < (const z1, z2: hwFloat) b : boolean; |
228 operator < (z1, z2: hwFloat) b : boolean; |
|
229 begin |
227 begin |
230 if z1.isNegative <> z2.isNegative then |
228 if z1.isNegative <> z2.isNegative then |
231 b:= z1.isNegative |
229 b:= z1.isNegative |
232 else |
230 else |
233 if z1.QWordValue = z2.QWordValue then |
231 if z1.QWordValue = z2.QWordValue then |
234 b:= false |
232 b:= false |
235 else |
233 else |
236 b:= (z1.QWordValue < z2.QWordValue) xor z1.isNegative |
234 b:= (z1.QWordValue < z2.QWordValue) xor z1.isNegative |
237 end; |
235 end; |
238 |
236 |
239 operator > (z1, z2: hwFloat) b : boolean; |
237 operator > (const z1, z2: hwFloat) b : boolean; |
240 begin |
238 begin |
241 if z1.isNegative <> z2.isNegative then |
239 if z1.isNegative <> z2.isNegative then |
242 b:= z2.isNegative |
240 b:= z2.isNegative |
243 else |
241 else |
244 if z1.QWordValue = z2.QWordValue then |
242 if z1.QWordValue = z2.QWordValue then |
245 b:= false |
243 b:= false |
246 else |
244 else |
247 b:= (z1.QWordValue > z2.QWordValue) xor z2.isNegative |
245 b:= (z1.QWordValue > z2.QWordValue) xor z2.isNegative |
248 end; |
246 end; |
249 |
247 |
250 function cstr(z: hwFloat): string; |
248 function cstr(const z: hwFloat): string; |
251 var tmpstr: string; |
249 var tmpstr: string; |
252 begin |
250 begin |
253 str(z.Round, cstr); |
251 str(z.Round, cstr); |
254 if z.Frac <> 0 then |
252 if z.Frac <> 0 then |
255 begin |
253 begin |
258 cstr:= cstr + '.' + tmpstr |
256 cstr:= cstr + '.' + tmpstr |
259 end; |
257 end; |
260 if z.isNegative then cstr:= '-' + cstr |
258 if z.isNegative then cstr:= '-' + cstr |
261 end; |
259 end; |
262 |
260 |
263 function hwRound(t: hwFloat): LongInt; |
261 function hwRound(const t: hwFloat): LongInt; |
264 begin |
262 begin |
265 if t.isNegative then hwRound:= -t.Round |
263 if t.isNegative then hwRound:= -t.Round |
266 else hwRound:= t.Round |
264 else hwRound:= t.Round |
267 end; |
265 end; |
268 |
266 |
269 function hwAbs(t: hwFloat): hwFloat; |
267 function hwAbs(const t: hwFloat): hwFloat; |
270 begin |
268 begin |
271 hwAbs:= t; |
269 hwAbs:= t; |
272 hwAbs.isNegative:= false |
270 hwAbs.isNegative:= false |
273 end; |
271 end; |
274 |
272 |
275 function hwSqr(t: hwFloat): hwFloat; |
273 function hwSqr(const t: hwFloat): hwFloat; |
276 begin |
274 begin |
277 hwSqr:= t * t |
275 hwSqr:= t * t |
278 end; |
276 end; |
279 |
277 |
280 function hwSqrt(t: hwFloat): hwFloat; |
278 function hwSqrt(const t: hwFloat): hwFloat; |
281 begin |
279 begin |
282 hwSqrt.isNegative:= false; |
280 hwSqrt.isNegative:= false; |
283 hwSqrt.QWordValue:= Round(sqrt(1.0 / $100000000 * (t.QWordValue)) * $100000000) |
281 hwSqrt.QWordValue:= Round(sqrt(1.0 / $100000000 * (t.QWordValue)) * $100000000) |
284 end; |
282 end; |
285 |
283 |
286 function Distance(dx, dy: hwFloat): hwFloat; |
284 function Distance(const dx, dy: hwFloat): hwFloat; |
287 var x, y: hwFloat; |
285 var x, y: hwFloat; |
288 Result: hwFloat; |
286 Result: hwFloat; |
289 begin |
287 begin |
290 x:= dx * dx; |
288 x:= dx * dx; |
291 y:= dy * dy; |
289 y:= dy * dy; |
292 Result:= x + y; |
290 Result:= x + y; |
293 Result.QWordValue:= Round(sqrt(1.0 / $100000000 * (Result.QWordValue)) * $100000000); |
291 Result.QWordValue:= Round(sqrt(1.0 / $100000000 * (Result.QWordValue)) * $100000000); |
294 Distance:= Result |
292 Distance:= Result |
295 end; |
293 end; |
296 |
294 |
297 function DistanceI(dx, dy: LongInt): hwFloat; |
295 function DistanceI(const dx, dy: LongInt): hwFloat; |
298 begin |
296 begin |
299 DistanceI:= Distance(int2hwFloat(dx), int2hwFloat(dy)) |
297 DistanceI:= Distance(int2hwFloat(dx), int2hwFloat(dy)) |
300 end; |
298 end; |
301 |
299 |
302 function SignAs(num, signum: hwFloat): hwFloat; |
300 function SignAs(const num, signum: hwFloat): hwFloat; |
303 begin |
301 begin |
304 SignAs:= num; |
302 SignAs:= num; |
305 SignAs.isNegative:= signum.isNegative |
303 SignAs.isNegative:= signum.isNegative |
306 end; |
304 end; |
307 |
305 |
308 {$INCLUDE SinTable.inc} |
306 {$INCLUDE SinTable.inc} |
309 |
307 |
310 function AngleSin(Angle: Longword): hwFloat; |
308 function AngleSin(const Angle: Longword): hwFloat; |
311 begin |
309 begin |
312 AngleSin.isNegative:= false; |
310 AngleSin.isNegative:= false; |
313 if Angle < 1024 then AngleSin.QWordValue:= SinTable[Angle] |
311 if Angle < 1024 then AngleSin.QWordValue:= SinTable[Angle] |
314 else AngleSin.QWordValue:= SinTable[2048 - Angle] |
312 else AngleSin.QWordValue:= SinTable[2048 - Angle] |
315 end; |
313 end; |
316 |
314 |
317 function AngleCos(Angle: Longword): hwFloat; |
315 function AngleCos(const Angle: Longword): hwFloat; |
318 begin |
316 begin |
319 AngleCos.isNegative:= Angle > 1024; |
317 AngleCos.isNegative:= Angle > 1024; |
320 if Angle < 1024 then AngleCos.QWordValue:= SinTable[1024 - Angle] |
318 if Angle < 1024 then AngleCos.QWordValue:= SinTable[1024 - Angle] |
321 else AngleCos.QWordValue:= SinTable[Angle - 1024] |
319 else AngleCos.QWordValue:= SinTable[Angle - 1024] |
322 end; |
320 end; |