Subject: square root From: johnl@informix.com (Jonathan Leffler) Newsgroups: comp.databases.informix Date: 9 Oct 1996 10:03:20 -0400 For SQRT, you could use the i4gl_sqrt() function and the underlying decsqrt() function in the attached shell archive. Note that this code uses DECIMAL types throughout and is therefore accurate up to 32 digits. For general trig, you could consider using the functions in the SELECT statement: SELECT SIN(3.1415) FROM SysTables WHERE Tabid = 1; but (a) that is a ludicrously slow way to do it, and (b) it almost certainly uses the C math library functions, rather than any more precise DECIMAL code, so the accuracy will not exceed about 14 digits. You can get those functions to exececute more quickly by using simple interface functions like i4gl_sin(): #include #include int i4gl_sin(int n) { double x; if (n != 1) fgl_fatal("i4gl_sin()", 1, -1318); popdub(&x); retdub(sin(x)); return(1); } If you are using an old version of I4GL, you may not have fglsys.h to declare the functions like popdub() and retdub() -- it is then simplest to omit the #include line. Yours, Jonathan Leffler (johnl@informix.com) #include >Does anyone know how to compute square root on 4GL? Also how to compute >logarithmic and trig functions? : "@(#)shar.sh 1.9" #! /bin/sh # # This is a shell archive. # Remove everything above this line and run sh on the resulting file. # If this archive is complete, you will see this message at the end: # "All files extracted" # # Created: Wed Oct 9 06:04:47 PDT 1996 by johnl at Informix Software Ltd. # Files archived in this archive: # decsqrt.c # i4glsqrt.c # #-------------------- if [ -f decsqrt.c -a "$1" != "-c" ] then echo shar: decsqrt.c already exists else echo 'x - decsqrt.c (2362 characters)' sed -e 's/^X//' >decsqrt.c <<'SHAR-EOF' X/* X@(#)File: decsqrt.c X@(#)Version: 1.2 X@(#)Last changed: 95/05/26 X@(#)Purpose: Square root of DECIMAL value X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1992 X@(#)Product: :PRODUCT: X*/ X X/*TABSTOP=4*/ X/*LINTLIBRARY*/ X X#include X#include X#include X X#ifdef TEST X#define PRINTLEN 32 X#define MAXITER 5 X#define ITERATIONS iter Xstatic int iter; X#else X#define ITERATIONS 2 /* Empirically, one would suffice! */ X#endif /* TEST */ X X#ifndef lint Xstatic char sccs[] = "@(#)decsqrt.c 1.2 95/05/26"; X#endif X Xdecsqrt(x, r1) Xdec_t *x; Xdec_t *r1; X{ X int s; X dec_t r; X dec_t t; X dec_t two; X double d; X int e; X int i; X X /* Check for zero and negative numbers */ X deccvdbl(0.0, &t); X if ((s = deccmp(x, &t)) <= 0) X { X *r1 = t; X return((s == 0) ? 0 : -EDOM); X } X X /* Deduce initial guess */ X r = *x; X e = r.dec_exp; X r.dec_exp &= 0x01; X dectodbl(&r, &d); X d = sqrt(d); X deccvdbl(d, &r); X r.dec_exp = (e + 1) / 2; X X deccvdbl(2.0, &two); X X for (i = 0; i < ITERATIONS; i++) X { X if ((s = decdiv(x, &r, &t)) != 0) X return(s); X if ((s = decadd(&r, &t, &t)) != 0) X return(s); X if ((s = decdiv(&t, &two, &r)) != 0) X return(s); X } X *r1 = r; X return(0); X} X X#ifdef TEST X X#include X X/* X#define NO_DECSCI X*/ X X#define DIM(x) (sizeof(x)/sizeof(*(x))) X Xchar *decimals[] = X{ X "-1.0", X "0.0", X "1.0", X "2.0", X "10.0", X "20.0", X "200.0", X "2000.0", X "20000.0", X "200000.0", X "2e30", X "2e31", X "2e32", X "2e33", X "2e-30", X "2e-31", X "2e-32", X "2e-33", X "2e120" X}; X Xmain() X{ X int i; X int j; X int k; X dec_t num; X dec_t res; X char buffer[40]; X char bufnum[40]; X X for (j = 0; j < DIM(decimals); j++) X { X if ((i = deccvasc(decimals[j], strlen(decimals[j]), &num)) != 0) X { X fprintf(stderr, "error %d from deccvasc processing %s\n", X i, decimals[j]); X exit(0); X } X X for (i = 1; i < MAXITER; i++) X { X iter = i; X k = decsqrt(&num, &res); X X#ifdef NO_DECSCI X dectoasc(&num, bufnum, sizeof(bufnum)-1, 16); X bufnum[sizeof(bufnum)-1] = '\0'; X dectoasc(&res, buffer, sizeof(buffer)-1, 16); X buffer[sizeof(buffer)-1] = '\0'; X#else X strcpy(bufnum, decsci(&num, PRINTLEN, 0)); X strcpy(buffer, decsci(&res, PRINTLEN, 0)); X#endif /* NO_DECSCI */ X X printf("%2d: %5d: SQRT(%s) = %s\n", i, k, bufnum, buffer); X num = res; X } X } X return(0); X} X X#endif /* TEST */ SHAR-EOF chmod 444 decsqrt.c if [ `wc -c i4glsqrt.c <<'SHAR-EOF' X/* X@(#)File: i4glsqrt.c X@(#)Version: 1.1 X@(#)Last changed: 96/10/09 X@(#)Purpose: I4GL-callable SQRT routine i4gl_sqrt() X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1996 X@(#)Product: :PRODUCT: X*/ X X/*TABSTOP=4*/ X X#include X#include X X#ifndef lint Xstatic const char sccs[] = "@(#)i4glsqrt.c 1.1 96/10/09"; X#endif X Xint i4gl_sqrt(int n) X{ X dec_t d; X dec_t r; X int s; X X if (n != 1) X fgl_fatal("i4gl_sqrt", 1, -1318); X X popdec(&d); X s = decsqrt(&d, &r); X if (s != 0) X fgl_fatal("i4gl_sqrt", 2, s); X X retdec(&r); X return(1); X} X X SHAR-EOF chmod 444 i4glsqrt.c if [ `wc -c