int main(int argc, char *argv[]) { decimal64 a; // working decimal64 number decNumber d; // working number decContext set; // working context char string[DECIMAL64_String]; // number->string buffer char hexes[25]; // decimal64->hex buffer int i; // counter if (argc<2) { // not enough words printf("Please supply a number.\n"); return 1; } decContextDefault(&set, DEC_INIT_DECIMAL64); // initialize set.traps=0; // no traps, thank you decimal64FromString(&a, argv[1], &set); // lay out the decimal64 as eight hexadecimal pairs for (i=0; i<8; i++) { sprintf(&hexes[i*3], "%02x ", a.bytes[i]); } decimal64ToNumber(&a, &d); decNumberToString(&d, string); printf("%s => %s=> %s\n", argv[1], hexes, string); return 0; } // main
char * decimal64ToEngString (const decimal64 *d64, char *string) { decNumber dn; /* work */ decimal64ToNumber (d64, &dn); decNumberToEngString (&dn, string); return string; }
void matrix_rowops(enum nilop op) { decNumber m, ydn, zdn, t; decimal64 *base, *r1, *r2; int rows, cols; int i; getXYZT(&m, &ydn, &zdn, &t); base = matrix_decomp(&m, &rows, &cols); if (base == NULL) return; i = dn_to_int(&ydn) - 1; if (i < 0 || i >= rows) { badrow: err(ERR_RANGE); return; } r1 = base + i * cols; if (op == OP_MAT_ROW_MUL) { for (i=0; i<cols; i++) { decimal64ToNumber(r1, &t); dn_multiply(&m, &zdn, &t); packed_from_number(r1++, &m); } } else { i = dn_to_int(&zdn) - 1; if (i < 0 || i >= rows) goto badrow; r2 = base + i * cols; if (op == OP_MAT_ROW_SWAP) { for (i=0; i<cols; i++) swap_reg((REGISTER *) r1++, (REGISTER *) r2++); } else { for (i=0; i<cols; i++) { decimal64ToNumber(r1, &ydn); decimal64ToNumber(r2++, &zdn); dn_multiply(&m, &zdn, &t); dn_add(&zdn, &ydn, &m); packed_from_number(r1++, &zdn); } } } }
int isinfd64 (_Decimal64 arg) { decNumber dn; decimal64 d64; __host_to_ieee_64 (arg, &d64); decimal64ToNumber (&d64, &dn); return (decNumberIsInfinite (&dn)); }
// a = a + b * k -- generalised matrix add and subtract decNumber *matrix_genadd(decNumber *r, const decNumber *k, const decNumber *b, const decNumber *a) { int arows, acols, brows, bcols; decNumber s, t, u; int i; decimal64 *abase = matrix_decomp(a, &arows, &acols); decimal64 *bbase = matrix_decomp(b, &brows, &bcols); if (abase == NULL || bbase == NULL) return NULL; if (arows != brows || acols != bcols) { err(ERR_MATRIX_DIM); return NULL; } for (i=0; i<arows*acols; i++) { decimal64ToNumber(bbase + i, &s); dn_multiply(&t, &s, k); decimal64ToNumber(abase + i, &s); dn_add(&u, &t, &s); packed_from_number(abase + i, &u); } return decNumberCopy(r, a); }
/* Decompose the passed in matrix identifier and extract the matrix from the * associated registers into the passed higher precision matrix. Optionally, * return the first register in the matrix and always return the dimensionality. * On error, return 0. */ static int matrix_lu_check(const decNumber *m, decimal128 *mat, decimal64 **mbase) { int rows, cols; decimal64 *base; decNumber t; int i; base = matrix_decomp(m, &rows, &cols); if (base == NULL) return 0; if (rows != cols) { err(ERR_MATRIX_DIM); return 0; } if (mat != NULL) { for (i=0; i<rows*rows; i++) { decimal64ToNumber(base+i, &t); packed128_from_number(mat+i, &t); } } if (mbase != NULL) *mbase = base; return rows; }
/* Solve the linear equation Ax = b. * We do this by utilising the LU decomposition passed in in A and solving * the linear equation Ly = b for y, where L is the lower diagonal triangular * matrix with unity along the diagonal. Then we solve the linear system * Ux = y, where U is the upper triangular matrix. */ static void matrix_pivoting_solve(decimal128 *LU, const decimal64 *b[], unsigned char pivot[], decNumber *x, int n) { int i, k; decNumber r, t; /* Solve the first linear equation Ly = b */ for (k=0; k<n; k++) { if (k != pivot[k]) { const decimal64 *swap = b[k]; b[k] = b[pivot[k]]; b[pivot[k]] = swap; } decimal64ToNumber(b[k], x + k); for (i=0; i<k; i++) { matrix_get128(&r, LU, k, i, n); dn_multiply(&t, &r, x+i); dn_subtract(x+k, x+k, &t); } } /* Solve the second linear equation Ux = y */ for (k=n-1; k>=0; k--) { //if(k != pivot[k]) swap(b[k], b[pivot[k]]); // undo pivoting from before for (i=k+1; i<n; i++) { matrix_get128(&r, LU, k, i, n); dn_multiply(&t, &r, x+i); dn_subtract(x+k, x+k, &t); } matrix_get128(&r, LU, k, k, n); #if 0 /* Check for singular matrix */ if (dn_eq0(&r)) return; #endif dn_divide(x+k, x+k, &r); } }
static void matrix_get(decNumber *r, const decimal64 *base, int row, int col, int ncols) { decimal64ToNumber(base + matrix_idx(row, col, ncols), r); }