Author Topic: reciprocal without division  (Read 3212 times)

0 Members and 1 Guest are viewing this topic.

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
reciprocal without division
« on: June 06, 2021, 09:11:41 am »
just for fun, a reciprocal function without division using the fast_pow trick http://www.qb64.org/wiki/C_Libraries
Code: QB64: [Select]
  1.     Sub memcpy (ByVal dest As _Offset, Byval source As _Offset, Byval bytes As Long)
  2.  
  3.  
  4. Print recip(3)
  5.  
  6. Function recip# (x#)
  7.     Dim As Double a
  8.     Dim As Long tmp
  9.     a = x#
  10.     memcpy _Offset(tmp), _Offset(a) + 4, 4
  11.     tmp = tmp - 1072632447
  12.     tmp = 1072632447 - tmp
  13.     memcpy _Offset(a) + 4, _Offset(tmp), 4
  14.     ' refine the initial approximation using the Newton-Raphson method
  15.     a = a * (2 - x# * a)
  16.     a = a * (2 - x# * a)
  17.     a = a * (2 - x# * a)
  18.     a = a * (2 - x# * a)
  19.     recip = a
  20.  
Quote
.3333333333333333
« Last Edit: June 06, 2021, 09:13:56 am by jack »

Offline david_uwi

  • Newbie
  • Posts: 71
    • View Profile
Re: reciprocal without division
« Reply #1 on: June 06, 2021, 10:22:34 am »
I'm an advocate of keeping it simple. These fancy optimization routines are all good using paper and pencil, but a computer is fast and even faster if the calculations required on each iteration are simple. So I present bisection for reciprocals...
Code: QB64: [Select]
  1. PRINT "input a number"
  2. y1 = x
  3. y2 = 0
  4. sq0 = 9999
  5.     sq1 = (y1 + y2) / 2
  6.     q1 = sq1 * x
  7.     IF q1 > 1! THEN y1 = sq1
  8.     IF q1 < 1! THEN y2 = sq1
  9.     IF ABS(sq1 - sq0) < .00000001 THEN EXIT DO
  10.     sq0 = sq1
  11. PRINT sq1
  12.  

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: reciprocal without division
« Reply #2 on: June 06, 2021, 11:04:21 am »
@david_uwi it doesn't count if you use division, see the thread's title
you could change / 2 by * 0.5, but I am willing to bet that my method is both much faster an more accurate
try x = 300000000000000#
« Last Edit: June 06, 2021, 11:10:43 am by jack »