Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!gatech!bloom-beacon!oberon!cit-vax!elroy!ames!ucbcad!ucbvax!A.CHEM.UPENN.EDU!YATES
From: YATES@A.CHEM.UPENN.EDU ("Yates, John H.")
Newsgroups: comp.os.vms
Subject: C help
Message-ID: <8707100533.AA24900@super.upenn.edu>
Date: Fri, 10-Jul-87 01:25:00 EDT
Article-I.D.: super.8707100533.AA24900
Posted: Fri Jul 10 01:25:00 1987
Date-Received: Sun, 12-Jul-87 14:12:29 EDT
Sender: daemon@ucbvax.BERKELEY.EDU
Distribution: world
Organization: The ARPA Internet
Lines: 106

C makes me nervous! Below is an example of the dangers involved with
floating point square roots. Is something wrong here or does one just
have to be extremely careful in C with:

1) assigning the proper lnk$libraries for your specific case
2) doing the type conversions explicitly, extra care for read in
   variables
3) being extremly careful with the /G switch, when needed vs. not
   needed.

Is there a bug here or is it just that C must never, ever be treated
as a high level language for floating point operations?

$ ty gsqrt.c
/*  This program gives an example of a G floating problem when a variable
    is input with scanf . First, the lnk$library logicals must be set
    in the proper order to get the G code, second, when this is done
    and the CC/G compiles the program, input variables evidently are
    NOT G type, you must use mth$cvt_d_g() to convert them!

$! The following logicals allow /G_Float qualifier to be used
$! with the CC command and Curses (a screen management package)
$!
$ define lnk$library     sys$library:vaxccurse
$ define lnk$library_1   sys$library:vaxcrtlg
$ define lnk$library_2   sys$library:vaxcrtl
     and use
$ cc/g gsqrt
$ link gsqrt
     to compile and link the code.

*/

#include math
#include stdio

main( )

{
 	double x1 ,x2, y1, y2, x3, y3;
        extern double mth$cvt_d_g();
        double sqrt();

        printf("Enter 9.0 for this test: ");
        scanf("%f", &x1);
        y1 = sqrt(x1);

        x2 = 9.0;
        y2 = sqrt(x2);

        x3 = mth$cvt_d_g(&x1);
        y3 = sqrt(x3);

        printf("\n\nsqrt of input number        %e = %e\n",x1, y1);
        printf("sqrt of hardwired number    %e = %e\n",x2, y2);
        printf("sqrt of d->g input number   %e = %e\n",x3, y3);
      
}
$ ty assign1.com
$! The following logicals allow /G_Float qualifier to be used
$! with the CC command and Curses (a screen management package)
$! according to the C manual, anyway
$!
$ define lnk$library   sys$library:vaxccurse
$ define lnk$library_1   sys$library:vaxcrtlg
$ define lnk$library_2 sys$library:vaxcrtl

$ @assign1
$ sh log lnk$*

(LNM$PROCESS_TABLE)

  "LNK$LIBRARY" = "SYS$LIBRARY:VAXCCURSE"
  "LNK$LIBRARY_1" = "SYS$LIBRARY:VAXCRTLG"
  "LNK$LIBRARY_2" = "SYS$LIBRARY:VAXCRTL"

(LNM$JOB_8028F360)

(LNM$GROUP_000011)

(LNM$SYSTEM_TABLE)
$ cc/lis gsqrt
$ link gsqrt
$ run gsqrt
Enter 9.0 for this test: 
9.0
sqrt of input number        9.000000e+00 = 2.250000e+00
sqrt of hardwired number    9.000000e+00 = 2.250000e+00
sqrt of d->g input number   7.578125e-01 = 6.562500e-01
$ cc/g gsqrt
$ link gsqrt
$ run gsqrt
Enter 9.0 for this test: 
9.0
sqrt of input number        4.294967e+09 = 6.553600e+04
sqrt of hardwired number    9.000000e+00 = 3.000000e+00
sqrt of d->g input number   9.000000e+00 = 3.000000e+00
$ ty gsqrt.lis       (to show C version no.)

GSQRT                                                            9-JUL-1987
 23:59:39    VAX C      V2.2-015                 Page 1
V1.0                                                             9-JUL-1987
 23:52:57    SYS$SYSDEVICE:[JY.CBUG]GSQRT.C;1 (1)


Is it any wonder I keep putting away my K and R? John