SHOW:
|
|
- or go back to the newest paste.
| 1 | #include <stdio.h> | |
| 2 | #include <stdlib.h> | |
| 3 | #include <math.h> | |
| 4 | ||
| 5 | #define ZERO 1e-10 | |
| 6 | ||
| 7 | struct Polynomial {
| |
| 8 | int deg; | |
| 9 | double* coeff; | |
| 10 | }; | |
| 11 | ||
| 12 | struct Polynomial* makePolynomial(int deg) {
| |
| 13 | struct Polynomial* p = malloc(sizeof(*p)); | |
| 14 | p->deg = deg; | |
| 15 | p->coeff = malloc((deg + 1) * sizeof(*p->coeff)); | |
| 16 | return p; | |
| 17 | } | |
| 18 | ||
| 19 | void findDeg(struct Polynomial* p) {
| |
| 20 | for (int i = p->deg; i >= 0; i--) | |
| 21 | if (fabs(p->coeff[i]) > ZERO) {
| |
| 22 | p->deg = i; | |
| 23 | return; | |
| 24 | } | |
| 25 | p->deg = 0; | |
| 26 | } | |
| 27 | ||
| 28 | ||
| 29 | struct Polynomial* addPolynomials(struct Polynomial* a, struct Polynomial* b) {
| |
| 30 | int newDeg = a->deg > b->deg ? a->deg : b->deg; | |
| 31 | int range = newDeg - abs(a->deg - b->deg); | |
| 32 | struct Polynomial* n = makePolynomial(newDeg); | |
| 33 | for (int i = range; i >= 0; i--) | |
| 34 | n->coeff[i] = a->coeff[i] + b->coeff[i]; | |
| 35 | if (a->deg > b->deg) | |
| 36 | for (int i = newDeg; i > range; i--) | |
| 37 | n->coeff[i] = a->coeff[i]; | |
| 38 | else | |
| 39 | for (int i = newDeg; i > range; i--) | |
| 40 | n->coeff[i] = b->coeff[i]; | |
| 41 | findDeg(n); | |
| 42 | return n; | |
| 43 | } | |
| 44 | ||
| 45 | struct Polynomial* substractPolynomials(struct Polynomial* a, struct Polynomial* b) {
| |
| 46 | int newDeg = a->deg > b->deg ? a->deg : b->deg; | |
| 47 | int range = newDeg - abs(a->deg - b->deg); | |
| 48 | struct Polynomial* n = makePolynomial(newDeg); | |
| 49 | for (int i = range; i >= 0; i--) | |
| 50 | n->coeff[i] = a->coeff[i] - b->coeff[i]; | |
| 51 | if (a->deg > b->deg) | |
| 52 | for (int i = newDeg; i > range; i--) | |
| 53 | n->coeff[i] = a->coeff[i]; | |
| 54 | else | |
| 55 | for (int i = newDeg; i > range; i--) | |
| 56 | n->coeff[i] = -b->coeff[i]; | |
| 57 | findDeg(n); | |
| 58 | return n; | |
| 59 | } | |
| 60 | ||
| 61 | struct Polynomial* multiplyPolynomials(struct Polynomial* a, struct Polynomial* b) {
| |
| 62 | struct Polynomial* n = makePolynomial(a->deg + b->deg); | |
| 63 | for (int i = 0; i < a->deg + 1; i++) | |
| 64 | for (int j = 0; j < b->deg + 1; j++) | |
| 65 | n->coeff[i + j] += a->coeff[i] * b->coeff[j]; | |
| 66 | return n; | |
| 67 | } | |
| 68 | ||
| 69 | struct Polynomial* dividePolynomials(struct Polynomial* a, struct Polynomial* b, struct Polynomial* r) {
| |
| 70 | struct Polynomial* q = makePolynomial(a->deg < b->deg ? 0 : a->deg); | |
| 71 | if (q->deg == 0) {
| |
| 72 | q->coeff[0] = 0.0; | |
| 73 | r->deg = a->deg; | |
| 74 | for(int i = r->deg; i >= 0; i--) | |
| 75 | r->coeff[i] = a->coeff[i]; | |
| 76 | return q; | |
| 77 | } | |
| 78 | struct Polynomial* temp = makePolynomial(a->deg); | |
| 79 | for (int i = 0; i < a->deg + 1; i++) {
| |
| 80 | temp->coeff[i] = a->coeff[i]; | |
| 81 | q->coeff[i] = 0.0; | |
| 82 | } | |
| 83 | for (int i = a->deg - b->deg; i >= 0; i--) {
| |
| 84 | q->coeff[i] = temp->coeff[b->deg + i] / b->coeff[b->deg]; | |
| 85 | for (int j = b->deg + i - 1; j >= i; j--) | |
| 86 | temp->coeff[j] -= q->coeff[i] * b->coeff[j - i]; | |
| 87 | } | |
| 88 | for (int i = 0; i < b->deg; i++) {
| |
| 89 | r->coeff[i] = temp->coeff[i]; | |
| 90 | } | |
| 91 | if (r->deg < a->deg) | |
| 92 | for (int i = b->deg; i < r->deg + 1; i++) | |
| 93 | r->coeff[i] = 0.0; | |
| 94 | else | |
| 95 | for (int i = b->deg; i < a->deg + 1; i++) | |
| 96 | r->coeff[i] = 0.0; | |
| 97 | free(temp->coeff); | |
| 98 | free(temp); | |
| 99 | findDeg(r); | |
| 100 | findDeg(q); | |
| 101 | return q; | |
| 102 | - | } |
| 102 | + | |
| 103 | ||
| 104 | struct Polynomial* GCD(struct Polynomial* a, struct Polynomial* b) {
| |
| 105 | struct Polynomial* temp = makePolynomial(a->deg); | |
| 106 | while (b->deg != 0 || fabs(b->coeff[0]) > ZERO) {
| |
| 107 | for(int i = 0; i < a->deg + 1; i++) | |
| 108 | temp->coeff[i] = a->coeff[i]; | |
| 109 | ||
| 110 | a->deg = b->deg; | |
| 111 | a->coeff = realloc(a->coeff, (a->deg+1)*sizeof(*a->coeff)); | |
| 112 | for(int i = 0; i < a->deg + 1; i++) | |
| 113 | a->coeff[i] = b->coeff[i]; | |
| 114 | ||
| 115 | dividePolynomials(temp, b, b); | |
| 116 | ||
| 117 | temp->deg = a->deg; | |
| 118 | temp->coeff = realloc(temp->coeff, (a->deg + 1) * sizeof(*temp->coeff)); | |
| 119 | } | |
| 120 | ||
| 121 | findDeg(a); | |
| 122 | ||
| 123 | free(temp); | |
| 124 | ||
| 125 | return a; | |
| 126 | } | |
| 127 | ||
| 128 | double Horner(struct Polynomial *p,double x) | |
| 129 | {
| |
| 130 | double v = p−>coeff[p−>deg]; | |
| 131 | for(int i=p−>deg−1;i >= 0;i−−) | |
| 132 | v = v * x +p−>coeff[i]; | |
| 133 | return v; | |
| 134 | } | |
| 135 |