|
|
1.1 ! root 1: #include "../h/rt.h" ! 2: ! 3: /* ! 4: * x ^ y - raise x to the y power. ! 5: */ ! 6: ! 7: power(nargs, arg2, arg1, arg0) ! 8: int nargs; ! 9: struct descrip arg2, arg1, arg0; ! 10: { ! 11: register int t1, t2; ! 12: union numeric n1, n2; ! 13: extern double pow(); ! 14: extern long ipow(); ! 15: ! 16: SetBound; ! 17: /* ! 18: * x and y must be numeric. Save the cvnum return values for later use. ! 19: */ ! 20: if ((t1 = cvnum(&arg1, &n1)) == NULL) ! 21: runerr(102, &arg1); ! 22: if ((t2 = cvnum(&arg2, &n2)) == NULL) ! 23: runerr(102, &arg2); ! 24: ! 25: if (t1 == T_LONGINT && t2 == T_LONGINT) ! 26: /* ! 27: * Both x and y are integers. Perform integer exponentiation ! 28: * and place the result in arg0 as the return value. ! 29: */ ! 30: mkint(ipow(n1.integer, n2.integer), &arg0); ! 31: else { ! 32: /* ! 33: * Either x or y is real, convert the other to a real, perform ! 34: * real exponentiation and place the result in arg0 as the ! 35: * return value. ! 36: */ ! 37: if (t1 == T_LONGINT) ! 38: n1.real = n1.integer; ! 39: if (t2 == T_LONGINT) ! 40: n2.real = n2.integer; ! 41: if (n1.real == 0.0 && n2.real <= 0.0) ! 42: /* ! 43: * Tried to raise zero to a negative power. ! 44: */ ! 45: runerr(204, NULL); ! 46: if (n1.real < 0.0 && t2 == T_REAL) ! 47: /* ! 48: * Tried to raise a negative number to a real power. ! 49: */ ! 50: runerr(206, NULL); ! 51: mkreal(pow(n1.real,n2.real), &arg0); ! 52: } ! 53: ClearBound; ! 54: } ! 55: ! 56: Opblock(power,2,"^") ! 57: ! 58: long ipow(n1, n2) ! 59: long n1, n2; ! 60: { ! 61: long result; ! 62: ! 63: if (n1 == 0 && n2 <= 0) ! 64: runerr(204, NULL); ! 65: if (n2 < 0) ! 66: return (0.0); ! 67: result = 1L; ! 68: while (n2 > 0) { ! 69: if (n2 & 01L) ! 70: result *= n1; ! 71: n1 *= n1; ! 72: n2 >>= 1; ! 73: } ! 74: return (result); ! 75: } ! 76:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.