83 |
82 |
84 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. |
85 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; inline; // Does NOT really round but returns the integer representation of the hwFloat without fractional digits. (-_0_9 -> -0, _1_5 -> _1) |
86 function hwAbs(const t: hwFloat): hwFloat; inline; // Returns the value of t with positive sign. |
85 function hwAbs(const t: hwFloat): hwFloat; inline; // Returns the value of t with positive sign. |
87 function hwSqr(const t: hwFloat): hwFloat; inline; // Returns the square value of parameter t. |
86 function hwSqr(const t: hwFloat): hwFloat; inline; // Returns the square value of parameter t. |
88 function hwPow(const t: hwFloat; p: LongWord): hwFloat; inline; // Returns the power of the value |
87 function hwSqrt1(const t: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t. |
89 function hwSqrt(const t: hwFloat): hwFloat; inline; // 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. |
90 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. |
91 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. |
92 function AngleSin(const Angle: Longword): hwFloat; |
91 function AngleSin(const Angle: Longword): hwFloat; |
93 function AngleCos(const Angle: Longword): hwFloat; |
92 function AngleCos(const Angle: Longword): hwFloat; |
94 function vector2Angle(const x, y: hwFloat): LongInt; |
93 function vector2Angle(const x, y: hwFloat): LongInt; |
95 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; inline; // Returns an hwFloat with the value of parameter num and the sign of signum. |
96 function hwSign(r: hwFloat): LongInt; inline; // Returns an integer with value 1 and sign of parameter r. |
95 function hwSign(r: hwFloat): LongInt; inline; // Returns an integer with value 1 and sign of parameter r. |
97 function hwSignf(r: real): LongInt; inline; // 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. |
98 function isZero(const z: hwFloat): boolean; inline; |
97 function isZero(const z: hwFloat): boolean; inline; |
99 {$IFDEF FPC} |
98 |
100 {$J-} |
|
101 {$ENDIF} |
|
102 {$WARNINGS OFF} |
99 {$WARNINGS OFF} |
103 |
|
104 |
|
105 // some hwFloat constants |
100 // some hwFloat constants |
106 |
|
107 const _1div1024: hwFloat = (isNegative: false; QWordValue: 4194304); |
101 const _1div1024: hwFloat = (isNegative: false; QWordValue: 4194304); |
108 _1div10000: hwFloat = (isNegative: false; QWordValue: 429496); |
102 _1div10000: hwFloat = (isNegative: false; QWordValue: 429496); |
109 _1div50000: hwFloat = (isNegative: false; QWordValue: 85899); |
103 _1div50000: hwFloat = (isNegative: false; QWordValue: 85899); |
110 _1div100000: hwFloat = (isNegative: false; QWordValue: 42950); |
104 _1div100000: hwFloat = (isNegative: false; QWordValue: 42950); |
111 _1div3: hwFloat = (isNegative: false; QWordValue: 1431655766); |
105 _1div3: hwFloat = (isNegative: false; QWordValue: 1431655766); |
149 _0_96: hwFloat = (isNegative: false; QWordValue: 4123168604); |
143 _0_96: hwFloat = (isNegative: false; QWordValue: 4123168604); |
150 _0_995: hwFloat = (isNegative: false; QWordValue: 4273492459); |
144 _0_995: hwFloat = (isNegative: false; QWordValue: 4273492459); |
151 _0_999: hwFloat = (isNegative: false; QWordValue: 4290672328); |
145 _0_999: hwFloat = (isNegative: false; QWordValue: 4290672328); |
152 _0: hwFloat = (isNegative: false; QWordValue: 0); |
146 _0: hwFloat = (isNegative: false; QWordValue: 0); |
153 _1: hwFloat = (isNegative: false; QWordValue: 4294967296); |
147 _1: hwFloat = (isNegative: false; QWordValue: 4294967296); |
154 _1_2: hwFloat = (isNegative: false; QWordValue: 1288490189*4); |
148 _1_2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 6 div 5 + 1); |
155 _1_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3 div 2); |
149 _1_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3 div 2); |
156 _1_6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 8 div 5); |
150 _1_6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 8 div 5); |
157 _1_9: hwFloat = (isNegative: false; QWordValue: 8160437862); |
151 _1_9: hwFloat = (isNegative: false; QWordValue: 8160437862); |
158 _2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 2); |
152 _2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 2); |
159 _2_4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12 div 5); |
153 _2_4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12 div 5); |
160 _3: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3); |
154 _3: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3); |
161 _3_2: hwFloat = (isNegative: false; QWordValue: 3435973837*4); |
155 _3_2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 16 div 5); |
162 _PI: hwFloat = (isNegative: false; QWordValue: 13493037704); |
156 _PI: hwFloat = (isNegative: false; QWordValue: 13493037704); |
163 _4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 4); |
157 _4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 4); |
164 _4_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 9 div 2); |
158 _4_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 9 div 2); |
165 _5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 5); |
159 _5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 5); |
166 _6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 6); |
160 _6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 6); |
167 _6_4: hwFloat = (isNegative: false; QWordValue: 3435973837 * 8); |
161 _6_4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 32 div 5); |
168 _7: hwFloat = (isNegative: false; QWordValue: 4294967296 * 7); |
162 _7: hwFloat = (isNegative: false; QWordValue: 4294967296 * 7); |
169 _10: hwFloat = (isNegative: false; QWordValue: 4294967296 * 10); |
163 _10: hwFloat = (isNegative: false; QWordValue: 4294967296 * 10); |
170 _12: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12); |
164 _12: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12); |
171 _16: hwFloat = (isNegative: false; QWordValue: 4294967296 * 16); |
165 _16: hwFloat = (isNegative: false; QWordValue: 4294967296 * 16); |
172 _19: hwFloat = (isNegative: false; QWordValue: 4294967296 * 19); |
166 _19: hwFloat = (isNegative: false; QWordValue: 4294967296 * 19); |
298 if z1.QWordValue = z2.QWordValue then |
284 if z1.QWordValue = z2.QWordValue then |
299 b:= false |
285 b:= false |
300 else |
286 else |
301 b:= (z1.QWordValue > z2.QWordValue) <> z2.isNegative |
287 b:= (z1.QWordValue > z2.QWordValue) <> z2.isNegative |
302 end; |
288 end; |
303 {$ENDIF} |
289 |
304 {$IFDEF WEB} |
290 operator - (const z1: hwFloat) z : hwFloat; inline; |
305 (* |
291 begin |
306 Mostly to be kind to JS as of 2012-08-27 where there is no int64/uint64. This may change though. |
|
307 *) |
|
308 operator = (const z1, z2: hwFloat) z : boolean; inline; |
|
309 begin |
|
310 z:= (z1.isNegative = z2.isNegative) and (z1.Frac = z2.Frac) and (z1.Round = z2.Round); |
|
311 end; |
|
312 |
|
313 operator <> (const z1, z2: hwFloat) z : boolean; inline; |
|
314 begin |
|
315 z:= (z1.isNegative <> z2.isNegative) or (z1.Frac <> z2.Frac) or (z1.Round <> z2.Round); |
|
316 end; |
|
317 |
|
318 operator + (const z1, z2: hwFloat) z : hwFloat; inline; |
|
319 begin |
|
320 if z1.isNegative = z2.isNegative then |
|
321 begin |
|
322 z:= z1; |
292 z:= z1; |
323 z.Frac:= z.Frac + z2.Frac; |
293 z.isNegative:= not z.isNegative |
324 z.Round:= z.Round + z2.Round; |
|
325 if z.Frac<z1.Frac then inc(z.Round) |
|
326 end |
|
327 else |
|
328 if (z1.Round > z2.Round) or ((z1.Round = z2.Round) and (z1.Frac > z2.Frac)) then |
|
329 begin |
|
330 z.isNegative:= z1.isNegative; |
|
331 z.Round:= z1.Round - z2.Round; |
|
332 z.Frac:= z1.Frac - z2.Frac; |
|
333 if z2.Frac > z1.Frac then dec(z.Round) |
|
334 end |
|
335 else |
|
336 begin |
|
337 z.isNegative:= z2.isNegative; |
|
338 z.Round:= z2.Round - z1.Round; |
|
339 z.Frac:= z2.Frac-z1.Frac; |
|
340 if z2.Frac < z1.Frac then dec(z.Round) |
|
341 end |
|
342 end; |
|
343 |
|
344 operator - (const z1, z2: hwFloat) z : hwFloat; inline; |
|
345 begin |
|
346 if z1.isNegative = z2.isNegative then |
|
347 if (z1.Round > z2.Round) or ((z1.Round = z2.Round) and (z1.Frac > z2.Frac)) then |
|
348 begin |
|
349 z.isNegative:= z1.isNegative; |
|
350 z.Round:= z1.Round - z2.Round; |
|
351 z.Frac:= z1.Frac-z2.Frac; |
|
352 if z2.Frac > z1.Frac then dec(z.Round) |
|
353 end |
|
354 else |
|
355 begin |
|
356 z.isNegative:= not z2.isNegative; |
|
357 z.Round:= z2.Round - z1.Round; |
|
358 z.Frac:= z2.Frac-z1.Frac; |
|
359 if z2.Frac < z1.Frac then dec(z.Round) |
|
360 end |
|
361 else |
|
362 begin |
|
363 z:= z1; |
|
364 z.Frac:= z.Frac + z2.Frac; |
|
365 z.Round:= z.Round + z2.Round; |
|
366 if z.Frac<z1.Frac then inc(z.Round) |
|
367 end |
|
368 end; |
|
369 |
|
370 operator < (const z1, z2: hwFloat) b : boolean; inline; |
|
371 begin |
|
372 if z1.isNegative xor z2.isNegative then |
|
373 b:= z1.isNegative |
|
374 else |
|
375 (* Not so sure this specialcase is a win w/ Round/Frac. have to do more tests anyway. |
|
376 if (z1.Round = z2.Round and (z1.Frac = z2.Frac)) then |
|
377 b:= false |
|
378 else *) |
|
379 b:= ((z1.Round < z2.Round) or ((z1.Round = z2.Round) and (z1.Frac < z2.Frac))) <> z1.isNegative |
|
380 end; |
|
381 |
|
382 operator > (const z1, z2: hwFloat) b : boolean; inline; |
|
383 begin |
|
384 if z1.isNegative xor z2.isNegative then |
|
385 b:= z2.isNegative |
|
386 else |
|
387 (* |
|
388 if z1.QWordValue = z2.QWordValue then |
|
389 b:= false |
|
390 else*) |
|
391 b:= ((z1.Round > z2.Round) or ((z1.Round = z2.Round) and (z1.Frac > z2.Frac))) <> z1.isNegative |
|
392 end; |
|
393 |
|
394 function isZero(const z: hwFloat): boolean; inline; |
|
395 begin |
|
396 isZero := (z.Round = 0) and (z.Frac = 0); |
|
397 end; |
|
398 {$ENDIF} |
|
399 |
|
400 operator - (const z1: hwFloat) z : hwFloat; inline; |
|
401 begin |
|
402 z:= z1; |
|
403 z.isNegative:= not z.isNegative |
|
404 end; |
294 end; |
405 |
295 |
406 |
296 |
407 operator * (const z1, z2: hwFloat) z : hwFloat; inline; |
297 operator * (const z1, z2: hwFloat) z : hwFloat; inline; |
408 begin |
298 begin |
409 z.isNegative:= z1.isNegative xor z2.isNegative; |
299 z.isNegative:= z1.isNegative xor z2.isNegative; |
410 z.QWordValue:= QWord(z1.Round) * z2.Frac + QWord(z1.Frac) * z2.Round + ((QWord(z1.Frac) * z2.Frac) shr 32); |
300 z.QWordValue:= QWord(z1.Round) * z2.Frac + QWord(z1.Frac) * z2.Round + ((QWord(z1.Frac) * z2.Frac) shr 32); |
411 z.Round:= z.Round + QWord(z1.Round) * z2.Round; |
301 z.Round:= z.Round + QWord(z1.Round) * z2.Round; |
412 end; |
302 end; |
413 |
303 |
414 operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; |
304 operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; |
415 begin |
305 begin |
416 z.isNegative:= z1.isNegative xor (z2 < 0); |
306 z.isNegative:= z1.isNegative xor (z2 < 0); |
417 z.QWordValue:= z1.QWordValue * abs(z2) |
307 z.QWordValue:= z1.QWordValue * abs(z2) |
418 end; |
308 end; |
419 |
309 |
420 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline; |
310 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline; |
421 var t: hwFloat; |
311 var t: QWord; |
422 begin |
312 begin |
423 z.isNegative:= z1.isNegative xor z2.isNegative; |
313 z.isNegative:= z1.isNegative xor z2.isNegative; |
424 z.Round:= z1.QWordValue div z2.QWordValue; |
314 z.Round:= z1.QWordValue div z2.QWordValue; |
425 t:= z1 - z2 * z.Round; |
315 t:= z1.QWordValue - z2.QWordValue * z.Round; |
426 if t.QWordValue = 0 then |
316 z.Frac:= 0; |
427 z.Frac:= 0 |
317 |
428 else |
318 if t <> 0 then |
429 begin |
319 begin |
430 while ((t.QWordValue and $8000000000000000) = 0) and ((z2.QWordValue and $8000000000000000) = 0) do |
320 while ((t and $FF00000000000000) = 0) and ((z2.QWordValue and $FF00000000000000) = 0) do |
431 begin |
321 begin |
432 t.QWordValue:= t.QWordValue shl 1; |
322 t:= t shl 8; |
433 z2.QWordValue:= z2.QWordValue shl 1 |
323 z2.QWordValue:= z2.QWordValue shl 8 |
434 end; |
324 end; |
435 if z2.Round > 0 then |
325 |
436 z.Frac:= (t.QWordValue) div (z2.Round) |
326 if z2.Round > 0 then |
437 else |
327 inc(z.QWordValue, t div z2.Round); |
438 z.Frac:= 0 |
328 end |
439 end |
|
440 end; |
329 end; |
441 |
330 |
442 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; |
331 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; |
443 begin |
332 begin |
444 z.isNegative:= z1.isNegative xor (z2 < 0); |
333 z.isNegative:= z1.isNegative xor (z2 < 0); |
445 z.QWordValue:= z1.QWordValue div abs(z2) |
334 z.QWordValue:= z1.QWordValue div abs(z2) |
446 end; |
335 end; |
447 |
336 |
448 function cstr(const z: hwFloat): shortstring; |
337 function cstr(const z: hwFloat): shortstring; |
449 var tmpstr: shortstring; |
338 var tmpstr: shortstring; |
450 begin |
339 begin |
451 str(z.Round, cstr); |
340 str(z.Round, cstr); |
452 if z.Frac <> 0 then |
341 if z.Frac <> 0 then |
453 begin |
342 begin |
454 str(z.Frac / $100000000, tmpstr); |
343 str(z.Frac / $100000000, tmpstr); |
455 delete(tmpstr, 1, 2); |
344 delete(tmpstr, 1, 2); |
456 cstr:= cstr + '.' + copy(tmpstr, 1, 10) |
345 cstr:= cstr + '.' + copy(tmpstr, 1, 10) |
457 end; |
346 end; |
458 if z.isNegative then |
347 if z.isNegative then |
459 cstr:= '-' + cstr |
348 cstr:= '-' + cstr |
460 end; |
349 end; |
461 |
350 |
462 function hwRound(const t: hwFloat): LongInt; |
351 function hwRound(const t: hwFloat): LongInt; |
463 begin |
352 begin |
464 if t.isNegative then |
353 if t.isNegative then |
465 hwRound:= -(t.Round and $7FFFFFFF) |
354 hwRound:= -(t.Round and $7FFFFFFF) |
466 else |
355 else |
467 hwRound:= t.Round and $7FFFFFFF |
356 hwRound:= t.Round and $7FFFFFFF |
468 end; |
357 end; |
469 |
358 |
470 function hwAbs(const t: hwFloat): hwFloat; |
359 function hwAbs(const t: hwFloat): hwFloat; |
471 begin |
360 begin |
472 hwAbs:= t; |
361 hwAbs:= t; |
473 hwAbs.isNegative:= false |
362 hwAbs.isNegative:= false |
474 end; |
363 end; |
475 |
364 |
476 function hwSqr(const t: hwFloat): hwFloat; inline; |
365 function hwSqr(const t: hwFloat): hwFloat; inline; |
477 begin |
366 begin |
478 hwSqr.isNegative:= false; |
367 hwSqr.isNegative:= false; |
479 hwSqr.QWordValue:= ((QWord(t.Round) * t.Round) shl 32) + QWord(t.Round) * t.Frac * 2 + ((QWord(t.Frac) * t.Frac) shr 32); |
368 hwSqr.QWordValue:= ((QWord(t.Round) * t.Round) shl 32) + QWord(t.Round) * t.Frac * 2 + ((QWord(t.Frac) * t.Frac) shr 32); |
480 end; |
369 end; |
481 |
370 |
482 function hwPow(const t: hwFloat;p: LongWord): hwFloat; |
371 function hwSqrt1(const t: hwFloat): hwFloat; |
483 begin |
|
484 hwPow:= t; |
|
485 if p mod 2 = 0 then hwPow.isNegative:= false; |
|
486 |
|
487 while p > 0 do |
|
488 begin |
|
489 hwPow.QWordValue:= QWord(hwPow.Round) * t.Frac + QWord(hwPow.Frac) * t.Round + ((QWord(hwPow.Frac) * t.Frac) shr 32); |
|
490 dec(p) |
|
491 end |
|
492 end; |
|
493 |
|
494 function hwSqrt(const t: hwFloat): hwFloat; |
|
495 const pwr = 8; // even value, feel free to adjust |
372 const pwr = 8; // even value, feel free to adjust |
496 rThreshold = 1 shl (pwr + 32); |
373 rThreshold: QWord = 1 shl (pwr + 32); |
497 lThreshold = 1 shl (pwr div 2 + 32); |
374 lThreshold: QWord = 1 shl (pwr div 2 + 32); |
498 var l, r: QWord; |
375 var l, r: QWord; |
499 c: hwFloat; |
376 c: hwFloat; |
500 begin |
377 begin |
501 hwSqrt.isNegative:= false; |
378 hwSqrt1.isNegative:= false; |
502 |
379 |
503 if t.Round = 0 then |
380 if t.Round = 0 then |
504 begin |
381 begin |
505 l:= t.QWordValue; |
382 l:= t.QWordValue; |
506 r:= $100000000 |
383 r:= $100000000 |
507 end |
384 end |
508 else |
385 else |
509 begin |
386 begin |
510 if t.QWordValue > $FFFFFFFFFFFF then // t.Round > 65535.9999 |
387 if t.QWordValue > $FFFFFFFFFFFF then // t.Round > 65535.9999 |
511 begin |
|
512 l:= $10000000000; // 256 |
|
513 r:= $FFFFFFFFFFFF; // 65535.9999 |
|
514 end else |
|
515 if t.QWordValue >= rThreshold then |
|
516 begin |
388 begin |
517 l:= lThreshold; |
389 l:= $10000000000; // 256 |
518 r:= $10000000000; // 256 |
390 r:= $FFFFFFFFFFFF; // 65535.9999 |
519 end else |
391 end |
|
392 else |
|
393 if t.QWordValue >= rThreshold then |
|
394 begin |
|
395 l:= lThreshold; |
|
396 r:= $10000000000; // 256 |
|
397 end |
|
398 else |
|
399 begin |
|
400 l:= $100000000; |
|
401 r:= lThreshold; |
|
402 end; |
|
403 end; |
|
404 |
|
405 repeat |
|
406 c.QWordValue:= (l + r) shr 1; |
|
407 if hwSqr(c).QWordValue > t.QWordValue then |
|
408 r:= c.QWordValue |
|
409 else |
|
410 l:= c.QWordValue |
|
411 until r - l <= 1; |
|
412 |
|
413 hwSqrt1.QWordValue:= l |
|
414 end; |
|
415 |
|
416 function hwSqrt(const x: hwFloat): hwFloat; |
|
417 var r, t, s, q: QWord; |
|
418 i: integer; |
|
419 begin |
|
420 hwSqrt.isNegative:= false; |
|
421 |
|
422 t:= $4000000000000000; |
|
423 r:= 0; |
|
424 q:= x.QWordValue; |
|
425 |
|
426 for i:= 0 to 31 do |
|
427 begin |
|
428 s:= r + t; |
|
429 r:= r shr 1; |
|
430 if s <= q then |
520 begin |
431 begin |
521 l:= $100000000; |
432 dec(q, s); |
522 r:= lThreshold; |
433 inc(r, t); |
523 end; |
434 end; |
524 end; |
435 t:= t shr 2; |
525 |
436 end; |
526 repeat |
437 |
527 c.QWordValue:= (l + r) shr 1; |
438 hwSqrt.QWordValue:= r shl 16 |
528 if hwSqr(c).QWordValue > t.QWordValue then |
439 end; |
529 r:= c.QWordValue |
440 |
530 else |
441 |
531 l:= c.QWordValue |
|
532 until r - l <= 1; |
|
533 |
|
534 hwSqrt.QWordValue:= l |
|
535 end; |
|
536 |
442 |
537 function Distance(const dx, dy: hwFloat): hwFloat; |
443 function Distance(const dx, dy: hwFloat): hwFloat; |
538 begin |
444 var r: QWord; |
539 Distance:= hwSqrt(hwSqr(dx) + hwSqr(dy)) |
445 begin |
|
446 r:= dx.QWordValue or dy.QWordValue; |
|
447 |
|
448 if r < $10000 then |
|
449 begin |
|
450 Distance.QWordValue:= r; |
|
451 Distance.isNegative:= false |
|
452 end |
|
453 else |
|
454 Distance:= hwSqrt(hwSqr(dx) + hwSqr(dy)) |
540 end; |
455 end; |
541 |
456 |
542 function DistanceI(const dx, dy: LongInt): hwFloat; |
457 function DistanceI(const dx, dy: LongInt): hwFloat; |
543 begin |
458 begin |
544 DistanceI:= hwSqrt(int2hwFloat(sqr(dx) + sqr(dy))) |
459 DistanceI:= hwSqrt(int2hwFloat(sqr(dx) + sqr(dy))) |
545 end; |
460 end; |
546 |
461 |
547 function SignAs(const num, signum: hwFloat): hwFloat; |
462 function SignAs(const num, signum: hwFloat): hwFloat; |
548 begin |
463 begin |
549 SignAs.QWordValue:= num.QWordValue; |
464 SignAs.QWordValue:= num.QWordValue; |
550 SignAs.isNegative:= signum.isNegative |
465 SignAs.isNegative:= signum.isNegative |
551 end; |
466 end; |
552 |
467 |
553 function hwSign(r: hwFloat): LongInt; |
468 function hwSign(r: hwFloat): LongInt; |
554 begin |
469 begin |
555 // yes, we have negative zero for a reason |
470 // yes, we have negative zero for a reason |