141 _0_96: hwFloat = (isNegative: false; QWordValue: 4123168604); |
149 _0_96: hwFloat = (isNegative: false; QWordValue: 4123168604); |
142 _0_995: hwFloat = (isNegative: false; QWordValue: 4273492459); |
150 _0_995: hwFloat = (isNegative: false; QWordValue: 4273492459); |
143 _0_999: hwFloat = (isNegative: false; QWordValue: 4290672328); |
151 _0_999: hwFloat = (isNegative: false; QWordValue: 4290672328); |
144 _0: hwFloat = (isNegative: false; QWordValue: 0); |
152 _0: hwFloat = (isNegative: false; QWordValue: 0); |
145 _1: hwFloat = (isNegative: false; QWordValue: 4294967296); |
153 _1: hwFloat = (isNegative: false; QWordValue: 4294967296); |
|
154 _1_2: hwFloat = (isNegative: false; QWordValue: 1288490189*4); |
146 _1_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3 div 2); |
155 _1_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3 div 2); |
|
156 _1_6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 8 div 5); |
147 _1_9: hwFloat = (isNegative: false; QWordValue: 8160437862); |
157 _1_9: hwFloat = (isNegative: false; QWordValue: 8160437862); |
148 _2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 2); |
158 _2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 2); |
|
159 _2_4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12 div 5); |
149 _3: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3); |
160 _3: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3); |
|
161 _3_2: hwFloat = (isNegative: false; QWordValue: 3435973837*4); |
|
162 _PI: hwFloat = (isNegative: false; QWordValue: 13493037704); |
150 _4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 4); |
163 _4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 4); |
|
164 _4_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 9 div 2); |
151 _5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 5); |
165 _5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 5); |
152 _6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 6); |
166 _6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 6); |
|
167 _6_4: hwFloat = (isNegative: false; QWordValue: 3435973837 * 8); |
|
168 _7: hwFloat = (isNegative: false; QWordValue: 4294967296 * 7); |
153 _10: hwFloat = (isNegative: false; QWordValue: 4294967296 * 10); |
169 _10: hwFloat = (isNegative: false; QWordValue: 4294967296 * 10); |
154 _12: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12); |
170 _12: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12); |
155 _16: hwFloat = (isNegative: false; QWordValue: 4294967296 * 16); |
171 _16: hwFloat = (isNegative: false; QWordValue: 4294967296 * 16); |
156 _19: hwFloat = (isNegative: false; QWordValue: 4294967296 * 19); |
172 _19: hwFloat = (isNegative: false; QWordValue: 4294967296 * 19); |
157 _20: hwFloat = (isNegative: false; QWordValue: 4294967296 * 20); |
173 _20: hwFloat = (isNegative: false; QWordValue: 4294967296 * 20); |
158 _25: hwFloat = (isNegative: false; QWordValue: 4294967296 * 25); |
174 _25: hwFloat = (isNegative: false; QWordValue: 4294967296 * 25); |
159 _30: hwFloat = (isNegative: false; QWordValue: 4294967296 * 30); |
175 _30: hwFloat = (isNegative: false; QWordValue: 4294967296 * 30); |
160 _40: hwFloat = (isNegative: false; QWordValue: 4294967296 * 40); |
176 _40: hwFloat = (isNegative: false; QWordValue: 4294967296 * 40); |
|
177 _41: hwFloat = (isNegative: false; QWordValue: 4294967296 * 41); |
|
178 _49: hwFloat = (isNegative: false; QWordValue: 4294967296 * 49); |
161 _50: hwFloat = (isNegative: false; QWordValue: 4294967296 * 50); |
179 _50: hwFloat = (isNegative: false; QWordValue: 4294967296 * 50); |
162 _70: hwFloat = (isNegative: false; QWordValue: 4294967296 * 70); |
180 _70: hwFloat = (isNegative: false; QWordValue: 4294967296 * 70); |
163 _90: hwFloat = (isNegative: false; QWordValue: 4294967296 * 90); |
181 _90: hwFloat = (isNegative: false; QWordValue: 4294967296 * 90); |
164 _128: hwFloat = (isNegative: false; QWordValue: 4294967296 * 128); |
182 _128: hwFloat = (isNegative: false; QWordValue: 4294967296 * 128); |
165 _180: hwFloat = (isNegative: false; QWordValue: 4294967296 * 180); |
183 _180: hwFloat = (isNegative: false; QWordValue: 4294967296 * 180); |
187 uses uSinTable; |
205 uses uSinTable; |
188 |
206 |
189 |
207 |
190 {$IFDEF FPC} |
208 {$IFDEF FPC} |
191 |
209 |
192 function int2hwFloat (const i: LongInt) : hwFloat; |
210 function int2hwFloat (const i: LongInt) : hwFloat; inline; |
193 begin |
211 begin |
194 int2hwFloat.isNegative:= i < 0; |
212 int2hwFloat.isNegative:= i < 0; |
195 int2hwFloat.Round:= abs(i); |
213 int2hwFloat.Round:= abs(i); |
196 int2hwFloat.Frac:= 0 |
214 int2hwFloat.Frac:= 0 |
197 end; |
215 end; |
198 |
216 |
199 function hwFloat2Float (const i: hwFloat) : extended; |
217 function hwFloat2Float (const i: hwFloat) : extended; inline; |
200 begin |
218 begin |
201 hwFloat2Float:= i.QWordValue / $100000000; |
219 hwFloat2Float:= i.Frac / $100000000 + i.Round; |
202 if i.isNegative then hwFloat2Float:= -hwFloat2Float; |
220 if i.isNegative then |
203 end; |
221 hwFloat2Float:= -hwFloat2Float; |
204 |
222 end; |
205 operator = (const z1, z2: hwFloat) z:boolean; inline; |
223 |
|
224 {$IFNDEF WEB} |
|
225 operator = (const z1, z2: hwFloat) z : boolean; inline; |
206 begin |
226 begin |
207 z:= (z1.isNegative = z2.isNegative) and (z1.QWordValue = z2.QWordValue); |
227 z:= (z1.isNegative = z2.isNegative) and (z1.QWordValue = z2.QWordValue); |
208 end; |
228 end; |
209 |
229 |
210 |
230 {$IFDEF PAS2C} |
211 operator + (const z1, z2: hwFloat) z : hwFloat; |
231 operator <> (const z1, z2: hwFloat) z : boolean; inline; |
|
232 begin |
|
233 z:= (z1.isNegative <> z2.isNegative) or (z1.QWordValue <> z2.QWordValue); |
|
234 end; |
|
235 {$ENDIF} |
|
236 |
|
237 operator + (const z1, z2: hwFloat) z : hwFloat; inline; |
212 begin |
238 begin |
213 if z1.isNegative = z2.isNegative then |
239 if z1.isNegative = z2.isNegative then |
214 begin |
240 begin |
215 z.isNegative:= z1.isNegative; |
241 z.isNegative:= z1.isNegative; |
216 z.QWordValue:= z1.QWordValue + z2.QWordValue |
242 z.QWordValue:= z1.QWordValue + z2.QWordValue |
217 end |
243 end |
218 else |
244 else |
219 if z1.QWordValue > z2.QWordValue then |
245 if z1.QWordValue > z2.QWordValue then |
220 begin |
246 begin |
221 z.isNegative:= z1.isNegative; |
247 z.isNegative:= z1.isNegative; |
222 z.QWordValue:= z1.QWordValue - z2.QWordValue |
248 z.QWordValue:= z1.QWordValue - z2.QWordValue |
223 end else |
249 end |
224 begin |
250 else |
225 z.isNegative:= z2.isNegative; |
251 begin |
226 z.QWordValue:= z2.QWordValue - z1.QWordValue |
252 z.isNegative:= z2.isNegative; |
227 end |
253 z.QWordValue:= z2.QWordValue - z1.QWordValue |
228 end; |
254 end |
229 |
255 end; |
230 operator - (const z1, z2: hwFloat) z : hwFloat; |
256 |
|
257 operator - (const z1, z2: hwFloat) z : hwFloat; inline; |
231 begin |
258 begin |
232 if z1.isNegative = z2.isNegative then |
259 if z1.isNegative = z2.isNegative then |
233 if z1.QWordValue > z2.QWordValue then |
260 if z1.QWordValue > z2.QWordValue then |
234 begin |
261 begin |
235 z.isNegative:= z1.isNegative; |
262 z.isNegative:= z1.isNegative; |
236 z.QWordValue:= z1.QWordValue - z2.QWordValue |
263 z.QWordValue:= z1.QWordValue - z2.QWordValue |
237 end else |
264 end |
238 begin |
265 else |
239 z.isNegative:= not z2.isNegative; |
266 begin |
240 z.QWordValue:= z2.QWordValue - z1.QWordValue |
267 z.isNegative:= not z2.isNegative; |
241 end |
268 z.QWordValue:= z2.QWordValue - z1.QWordValue |
242 else begin |
269 end |
243 z.isNegative:= z1.isNegative; |
270 else |
244 z.QWordValue:= z1.QWordValue + z2.QWordValue |
271 begin |
245 end |
272 z.isNegative:= z1.isNegative; |
246 end; |
273 z.QWordValue:= z1.QWordValue + z2.QWordValue |
247 |
274 end |
248 operator - (const z1: hwFloat) z : hwFloat; |
275 end; |
|
276 |
|
277 function isZero(const z: hwFloat): boolean; inline; |
|
278 begin |
|
279 isZero := z.QWordValue = 0; |
|
280 end; |
|
281 |
|
282 operator < (const z1, z2: hwFloat) b : boolean; inline; |
|
283 begin |
|
284 if z1.isNegative xor z2.isNegative then |
|
285 b:= z1.isNegative |
|
286 else |
|
287 if z1.QWordValue = z2.QWordValue then |
|
288 b:= false |
|
289 else |
|
290 b:= not((z1.QWordValue = z2.QWordValue) or ((z2.QWordValue < z1.QWordValue) <> z1.isNegative)) |
|
291 end; |
|
292 |
|
293 operator > (const z1, z2: hwFloat) b : boolean; inline; |
|
294 begin |
|
295 if z1.isNegative xor z2.isNegative then |
|
296 b:= z2.isNegative |
|
297 else |
|
298 if z1.QWordValue = z2.QWordValue then |
|
299 b:= false |
|
300 else |
|
301 b:= (z1.QWordValue > z2.QWordValue) <> z2.isNegative |
|
302 end; |
|
303 {$ENDIF} |
|
304 {$IFDEF WEB} |
|
305 (* |
|
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; |
|
323 z.Frac:= z.Frac + z2.Frac; |
|
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; |
249 begin |
401 begin |
250 z:= z1; |
402 z:= z1; |
251 z.isNegative:= not z.isNegative |
403 z.isNegative:= not z.isNegative |
252 end; |
404 end; |
253 |
405 |
254 |
406 |
255 operator * (const z1, z2: hwFloat) z : hwFloat; |
407 operator * (const z1, z2: hwFloat) z : hwFloat; inline; |
256 begin |
408 begin |
257 z.isNegative:= z1.isNegative xor z2.isNegative; |
409 z.isNegative:= z1.isNegative xor z2.isNegative; |
258 z.QWordValue:= QWord(z1.Round) * z2.Frac + |
410 z.QWordValue:= QWord(z1.Round) * z2.Frac + QWord(z1.Frac) * z2.Round + ((QWord(z1.Frac) * z2.Frac) shr 32); |
259 QWord(z1.Frac) * z2.Round + |
|
260 ((QWord(z1.Frac) * z2.Frac) shr 32); |
|
261 z.Round:= z.Round + QWord(z1.Round) * z2.Round; |
411 z.Round:= z.Round + QWord(z1.Round) * z2.Round; |
262 end; |
412 end; |
263 |
413 |
264 operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; |
414 operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; |
265 begin |
415 begin |
266 z.isNegative:= z1.isNegative xor (z2 < 0); |
416 z.isNegative:= z1.isNegative xor (z2 < 0); |
267 z.QWordValue:= z1.QWordValue * abs(z2) |
417 z.QWordValue:= z1.QWordValue * abs(z2) |
268 end; |
418 end; |
269 |
419 |
270 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; |
420 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline; |
271 var t: hwFloat; |
421 var t: hwFloat; |
272 begin |
422 begin |
273 z.isNegative:= z1.isNegative xor z2.isNegative; |
423 z.isNegative:= z1.isNegative xor z2.isNegative; |
274 z.Round:= z1.QWordValue div z2.QWordValue; |
424 z.Round:= z1.QWordValue div z2.QWordValue; |
275 t:= z1 - z2 * z.Round; |
425 t:= z1 - z2 * z.Round; |
276 if t.QWordValue = 0 then |
426 if t.QWordValue = 0 then |
277 z.Frac:= 0 |
427 z.Frac:= 0 |
278 else |
428 else |
279 begin |
429 begin |
280 while ((t.QWordValue and $8000000000000000) = 0) and |
430 while ((t.QWordValue and $8000000000000000) = 0) and ((z2.QWordValue and $8000000000000000) = 0) do |
281 ((z2.QWordValue and $8000000000000000) = 0) do |
431 begin |
282 begin |
432 t.QWordValue:= t.QWordValue shl 1; |
283 t.QWordValue:= t.QWordValue shl 1; |
433 z2.QWordValue:= z2.QWordValue shl 1 |
284 z2.QWordValue:= z2.QWordValue shl 1 |
434 end; |
285 end; |
435 if z2.Round > 0 then |
286 if z2.Round > 0 then z.Frac:= (t.QWordValue) div (z2.Round) |
436 z.Frac:= (t.QWordValue) div (z2.Round) |
287 else z.Frac:= 0 |
437 else |
288 end |
438 z.Frac:= 0 |
289 end; |
439 end |
290 |
440 end; |
291 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; |
441 |
|
442 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; |
292 begin |
443 begin |
293 z.isNegative:= z1.isNegative xor (z2 < 0); |
444 z.isNegative:= z1.isNegative xor (z2 < 0); |
294 z.QWordValue:= z1.QWordValue div abs(z2) |
445 z.QWordValue:= z1.QWordValue div abs(z2) |
295 end; |
446 end; |
296 |
447 |
297 operator < (const z1, z2: hwFloat) b : boolean; |
|
298 begin |
|
299 if z1.isNegative xor z2.isNegative then |
|
300 b:= z1.isNegative |
|
301 else |
|
302 if z1.QWordValue = z2.QWordValue then |
|
303 b:= false |
|
304 else |
|
305 b:= (z1.QWordValue < z2.QWordValue) xor z1.isNegative |
|
306 end; |
|
307 |
|
308 operator > (const z1, z2: hwFloat) b : boolean; |
|
309 begin |
|
310 if z1.isNegative xor z2.isNegative then |
|
311 b:= z2.isNegative |
|
312 else |
|
313 if z1.QWordValue = z2.QWordValue then |
|
314 b:= false |
|
315 else |
|
316 b:= (z1.QWordValue > z2.QWordValue) xor z2.isNegative |
|
317 end; |
|
318 |
|
319 function cstr(const z: hwFloat): shortstring; |
448 function cstr(const z: hwFloat): shortstring; |
320 var tmpstr: shortstring; |
449 var tmpstr: shortstring; |
321 begin |
450 begin |
322 str(z.Round, cstr); |
451 str(z.Round, cstr); |
323 if z.Frac <> 0 then |
452 if z.Frac <> 0 then |
324 begin |
453 begin |
325 str(z.Frac / $100000000:1:10, tmpstr); |
454 str(z.Frac / $100000000, tmpstr); |
326 delete(tmpstr, 1, 2); |
455 delete(tmpstr, 1, 2); |
327 cstr:= cstr + '.' + tmpstr |
456 cstr:= cstr + '.' + copy(tmpstr, 1, 10) |
328 end; |
457 end; |
329 if z.isNegative then cstr:= '-' + cstr |
458 if z.isNegative then |
|
459 cstr:= '-' + cstr |
330 end; |
460 end; |
331 |
461 |
332 function hwRound(const t: hwFloat): LongInt; |
462 function hwRound(const t: hwFloat): LongInt; |
333 begin |
463 begin |
334 if t.isNegative then hwRound:= -(t.Round and $7FFFFFFF) |
464 if t.isNegative then |
335 else hwRound:= t.Round and $7FFFFFFF |
465 hwRound:= -(t.Round and $7FFFFFFF) |
|
466 else |
|
467 hwRound:= t.Round and $7FFFFFFF |
336 end; |
468 end; |
337 |
469 |
338 function hwAbs(const t: hwFloat): hwFloat; |
470 function hwAbs(const t: hwFloat): hwFloat; |
339 begin |
471 begin |
340 hwAbs:= t; |
472 hwAbs:= t; |
341 hwAbs.isNegative:= false |
473 hwAbs.isNegative:= false |
342 end; |
474 end; |
343 |
475 |
344 function hwSqr(const t: hwFloat): hwFloat; |
476 function hwSqr(const t: hwFloat): hwFloat; inline; |
345 begin |
477 begin |
346 hwSqr.isNegative:= false; |
478 hwSqr.isNegative:= false; |
347 hwSqr.QWordValue:= |
479 hwSqr.QWordValue:= ((QWord(t.Round) * t.Round) shl 32) + QWord(t.Round) * t.Frac * 2 + ((QWord(t.Frac) * t.Frac) shr 32); |
348 ((QWord(t.Round) * t.Round) shl 32) |
480 end; |
349 + QWord(t.Round) * t.Frac * 2 |
481 |
350 + ((QWord(t.Frac) * t.Frac) shr 32); |
482 function hwPow(const t: hwFloat;p: LongWord): 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 |
351 end; |
492 end; |
352 |
493 |
353 function hwSqrt(const t: hwFloat): hwFloat; |
494 function hwSqrt(const t: hwFloat): hwFloat; |
|
495 const pwr = 8; // even value, feel free to adjust |
|
496 rThreshold = 1 shl (pwr + 32); |
|
497 lThreshold = 1 shl (pwr div 2 + 32); |
354 var l, r: QWord; |
498 var l, r: QWord; |
355 c: hwFloat; |
499 c: hwFloat; |
356 begin |
500 begin |
357 hwSqrt.isNegative:= false; |
501 hwSqrt.isNegative:= false; |
358 |
502 |
359 if t.Round = 0 then |
503 if t.Round = 0 then |
360 begin |
504 begin |
361 l:= t.QWordValue; |
505 l:= t.QWordValue; |
362 r:= $100000000 |
506 r:= $100000000 |
363 end else |
507 end |
364 begin |
508 else |
365 l:= $100000000; |
509 begin |
366 r:= t.QWordValue div 2 + $80000000; // r:= t / 2 + 0.5 |
510 if t.QWordValue > $FFFFFFFFFFFF then // t.Round > 65535.9999 |
367 if r > $FFFFFFFFFFFF then r:= $FFFFFFFFFFFF |
511 begin |
368 end; |
512 l:= $10000000000; // 256 |
|
513 r:= $FFFFFFFFFFFF; // 65535.9999 |
|
514 end else |
|
515 if t.QWordValue >= rThreshold then |
|
516 begin |
|
517 l:= lThreshold; |
|
518 r:= $10000000000; // 256 |
|
519 end else |
|
520 begin |
|
521 l:= $100000000; |
|
522 r:= lThreshold; |
|
523 end; |
|
524 end; |
369 |
525 |
370 repeat |
526 repeat |
371 c.QWordValue:= (l + r) div 2; |
527 c.QWordValue:= (l + r) shr 1; |
372 if hwSqr(c).QWordValue > t.QWordValue then r:= c.QWordValue else l:= c.QWordValue |
528 if hwSqr(c).QWordValue > t.QWordValue then |
|
529 r:= c.QWordValue |
|
530 else |
|
531 l:= c.QWordValue |
373 until r - l <= 1; |
532 until r - l <= 1; |
374 |
533 |
375 hwSqrt.QWordValue:= l |
534 hwSqrt.QWordValue:= l |
376 end; |
535 end; |
377 |
536 |