summaryrefslogtreecommitdiff
path: root/gnu/lib/libf2c/libF77/pow_zi.c
blob: 214db3d7a0fb3a4c7c29383eda391adad3376beb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "f2c.h"

extern void z_div (doublecomplex *, doublecomplex *, doublecomplex *);
void
pow_zi (doublecomplex * p, doublecomplex * a, integer * b)	/* p = a**b  */
{
  integer n;
  unsigned long u;
  double t;
  doublecomplex q, x;
  static doublecomplex one = { 1.0, 0.0 };

  n = *b;
  q.r = 1;
  q.i = 0;

  if (n == 0)
    goto done;
  if (n < 0)
    {
      n = -n;
      z_div (&x, &one, a);
    }
  else
    {
      x.r = a->r;
      x.i = a->i;
    }

  for (u = n;;)
    {
      if (u & 01)
	{
	  t = q.r * x.r - q.i * x.i;
	  q.i = q.r * x.i + q.i * x.r;
	  q.r = t;
	}
      if (u >>= 1)
	{
	  t = x.r * x.r - x.i * x.i;
	  x.i = 2 * x.r * x.i;
	  x.r = t;
	}
      else
	break;
    }
done:
  p->i = q.i;
  p->r = q.r;
}