[comp.os.vms] C help

YATES@A.CHEM.UPENN.EDU ("Yates, John H.") (07/10/87)

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

tli@sargas.usc.edu (Tony Li) (07/12/87)

In article <8707100533.AA24900@super.upenn.edu> YATES@A.CHEM.UPENN.EDU ("Yates, John H.") writes:
    C makes me nervous! Below is an example of the dangers involved with
    floating point square roots. 

     	double x1 ,x2, y1, y2, x3, y3;
	...    
        printf("Enter 9.0 for this test: ");
        scanf("%f", &x1);
	...    
        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);

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

Please get out your K&R and your Vax C manual.  Floats and doubles and
G floating are *NOT* interchangeable.  When you called scanf, you
asked it to read a float.  It did, and stored it in x1.  Scanf has no
idea that x1 is a g-float, so it just read an f-float and stored the
binary representation into x1.  Since the binary representation for
f-float and g-float is radically different, you would seem to get
garbage.  

The trick here is to tell the runtimes to expect a double precision
value.  This can easily be done by specifying "%lf" and "%le".

;-)

Tony Li - USC University Computing Services	"Fene mele kiki bobo"
Uucp: oberon!tli						-- Joe Isuzu
Bitnet: tli@uscvaxq, tli@ramoth
Internet: tli@sargas.usc.edu

ik.naggum-erik@siri.uio.no (07/13/87)

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

ik.naggum-erik@siri.uio.no (07/15/87)

"The best way to predict the future is to invent it." (EVB S/W Eng, Inc.)
Message-ID: <12317866627.139.IK.NAGGUM-ERIK@SIRI>


Yates@a.chem.upenn.edu writes:
> 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:
 ......
> 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?
 ......
> $! 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
 ......
> Is it any wonder I keep putting away my K and R? John

John,

I regard myself as an expert in C and Unix.  I have read the Ansi Standard Draft of 10/10/86, and Kernighan and
Richie: The C Programming Language.  With 3 years of experience in C
programming, and 200K source lines on my conscience, I have some
comments to your article, blaming C for various flaws in floating point
operations on a VAX (model X?), using VAX C version 2.2 under VMS.

I took the time to go through a lot of documentation tonight, and
visited those for (AT&T) Unix Version 7, System III and System V, for
SVID, for BSD release 4.3 and Ultrix 2.0, for XENIX 3 and XENIX 5, and
finally those of SUN OS.  (Insert list of trademark owners here.)

Nowhere can I find a reference to G-floating or, in fact, any other
specific implementation of floating point numbers, as part of the C
language.  Rather, I have found that each machine and each implementor
decides which formats to use, and that they are more an attribute of the
hardware than of the language definition.

You ask,
> Is it any wonder I keep putting away my K and R?

Why not put away your VAX VMS or your VAX C, instead?

Erik Naggum		ARPA:  enag@siri.uio.no or enag%siri@ifi.uio.no
Manager			SNAIL: POB 1560 Vika, N-0118 OSLO 1, NORWAY
Naggum Software		PHONE: (intl)+47-2-549-163  (0600-1200 GMT)
-------