kmh@ihlpm.ATT.COM (Kirk Hoyer) (07/02/87)
I have also encountered problems with floating point numbers, but mine seems to be different. I have applied the three compiler patches that Borland has posted on Compuserve, but the problem still persists. Given the following program: main() { float f1, f2, f3, ffunc(); f1 = 0.1234; f2 = 0.5678; printf("main: f1=%f f2=%f\n",f1,f2); f3 = ffunc( f1, f2 ); printf("main: f3=%f\n",f3); } float ffunc( f1, f2 ) float f1, f2; { float f3; printf("ffunc: f1=%f f2=%f\n",f1,f2); f3 = 0.9876; printf("ffunc: f3=%f\n",f3); return( f3 ); } When this program is compiled and executed (I used the tcc compiler), the values of f1 and f2 printed in the routine ffunc() are not the same as the values printed in the main program. The problem seems to go away if the declaration in the main program for ffunc() is changed as follows: float f1, f2, f3, ffunc( float, float ); Since Borland claims that both declaration styles are supported, it seems to me that both should work. If I could make floating point work by simply adopting this "modern" style, I could live with it. Unfortunately, I wrote a more meaningful program that ran fine on the large UNIX system at work, but failed miserably on my PC at home. After changing all my function declarations to the modern style, the program still bombed. I found the following problem: when a float function returned the value f1 like this: return( f1 ); the calling routine received the value of f1 as 0, even though f1 was printed as having a non-zero value just before returning. When I changed the return to look like this: f1 = 100. * f1; return( f1 ); the calling routine received the expected value. This indicates to me that the handling of floats as parameters and returned values in TURBO C has some serious flaws that have yet to be corrected. I will notify Borland of these problems, and hopefully they will have some answers soon.
kmh@ihlpm.ATT.COM (Kirk Hoyer) (07/06/87)
Paul Chisholm correctly pointed out to me that, according to K & R section 2.7, floats are cast to doubles when used as function arguments. Many thanks to Paul for his observation. (I should note that the "cc" compiler on the large UNIX system I use at work was able to handle the program correctly, even though floats and double are different sizes.) This explains the first problem cited in my posting, but not the second. I will try to provide a more concrete example of this problem in a future posting. Kirk Hoyer
joe@mdbs.UUCP (Joe Greer) (07/07/87)
In article <1236@ihlpm.ATT.COM> kmh@ihlpm.ATT.COM (Kirk Hoyer) writes: > >When this program is compiled and executed (I used the tcc compiler), >the values of f1 and f2 printed in the routine ffunc() are not the same >as the values printed in the main program. > >The problem seems to go away if the declaration in the main program for >ffunc() is changed as follows: > > float f1, f2, f3, ffunc( float, float ); > >Since Borland claims that both declaration styles are supported, it >seems to me that both should work. > I have run into this kind of problem with a lot of different compilers both in the MSDOS environment and in the unix environment. The problems seem to crop up when the compiler tries to support the IEEE floating point standard. By default, all floating point numbers are converted to double precision when passed through a subroutine call. The problem is that with ieee floating point, doubles and floats have very little in common and it is a non-trivial task to convert from one to the other. Now, in your example, when you passed your floats to the function, they were converted to doubles. If you look at your function, you decided to treat these doubles as floats. This results in numbers that are different (remember that unlike vaxen, ieee floats and doubles are different). This is analogous(sp?) to passing a short to a routine which expects longs. In short, *I* claim that this isn't a bug, rather it is a feature. You should use doubles if you want to let the compiler use its default type. I have yet to find a compiler that supports ieee and doesn't have this particular *feature*. Joe Greer ...ihnp4!pur-ee!mdbs!joe
darrylo@hpsrlc.HP.COM (Darryl Okahata) (07/07/87)
In comp.sys.ibm.pc, kmh@ihlpm.ATT.COM (Kirk Hoyer) writes: > Paul Chisholm correctly pointed out to me that, according to K & R section > 2.7, floats are cast to doubles when used as function arguments. Many > thanks to Paul for his observation. (I should note that the "cc" compiler > on the large UNIX system I use at work was able to handle the program correctly, > even though floats and double are different sizes.) > > This explains the first problem cited in my posting, but not the second. > I will try to provide a more concrete example of this problem in a future > posting. > > Kirk Hoyer > ---------- I've heard that Turbo C WILL pass a float as a float (NOT as a double) if function prototyping is used. For example: foo(xyzzy) float xyzzy; { ... } main() { foo(42.0); } will have a (double) (42.0) passed to foo(). However, if the following is used: foo(float xyzzy) { ... } main() { foo(42.0); } a (float) (42.0) will be passed to foo(). No conversion is done in this case. Is this ANSI C??? -- Darryl Okahata hplabs!hpcea!hpsrla!darrylo CompuServe: 75206,3074 Disclaimer: the above is the author's personal opinion and is not the opinion or policy of his employer or of the little green men that have been following him all day.
krause@uicsrd.UUCP (07/09/87)
Written 7:55 am Jul 7, 1987 by joe@mdbs.UUCP in uicsrd:comp.sys.ibm.pc: >In article <1236@ihlpm.ATT.COM> kmh@ihlpm.ATT.COM (Kirk Hoyer) writes: >> >>When this program is compiled and executed (I used the tcc compiler), >>the values of f1 and f2 printed in the routine ffunc() are not the same >>as the values printed in the main program. >> >>The problem seems to go away if the declaration in the main program for >>ffunc() is changed as follows: >> >> float f1, f2, f3, ffunc( float, float ); > >I have run into this kind of problem with a lot of different compilers both >in the MSDOS environment and in the unix environment. The problems seem to >crop up when the compiler tries to support the IEEE floating point standard. >By default, all floating point numbers are converted to double precision >when passed through a subroutine call. The problem is that with ieee >floating point, doubles and floats have very little in common and it is a >non-trivial task to convert from one to the other. Now, in your example, >when you passed your floats to the function, they were converted to doubles. >If you look at your function, you decided to treat these doubles as floats. >This results in numbers that are different (remember that unlike vaxen, ieee >floats and doubles are different). This is analogous(sp?) to passing a short >to a routine which expects longs. In short, *I* claim that this isn't a bug, >rather it is a feature. You should use doubles if you want to let the compiler >use its default type. I have yet to find a compiler that supports ieee and >doesn't have this particular *feature*. > Joe Greer > ...ihnp4!pur-ee!mdbs!joe I think there may be a general misunderstanding about this point. Yes, it is true that K&R C requires floats to change to doubles on a function call, but it ALSO requires the callED routine to understand that it's "float" arguments are really coming in as "doubles". For a ref., check K&R, Appendix A, sect. 10.1, p. 205: C converts all float actual parameters to double, so formal parameters declared float have their declaration adjusted to read double. ANSI allows floats to be passed and received when a prototype is in scope for both the callER and callEE. But without prototypes, the compiler should default to doubles on both ends. I guess I don't see how this relates to IEEE reals. Besides Turbo C, I've used various compilers for MS-DOS/UNIX, including Lattice, Datalight, and Berkeley 4.x UNIX. I've never encountered a problem like in Turbo C (even in Datalight, about which I can't say enough negative things...but that's for another day). It may be a pain to convert from float to double and back, but the compiler has to do it. When I had this problem with Turbo C, I dug out various public-domain sources that used floating point--there was stuff written for everything from Aztec C (MSDOS) to the Amiga to Vaxen, and lots of it used floats as parameters. And without prototypes (it was older code). Anyway, that's my 2 cents. Cheers! James Krause
ralf@b.gp.cs.cmu.edu (Ralf Brown) (07/11/87)
In article <1236@ihlpm.ATT.COM> kmh@ihlpm.ATT.COM (Kirk Hoyer) writes: > >I have also encountered problems with floating point numbers, >but mine seems to be different. I have applied the three >compiler patches that Borland has posted on Compuserve, but the problem >still persists. > >Given the following program: >[deleted for brevity] > >When this program is compiled and executed (I used the tcc compiler), >the values of f1 and f2 printed in the routine ffunc() are not the same >as the values printed in the main program. > >The problem seems to go away if the declaration in the main program for >ffunc() is changed as follows: > > float f1, f2, f3, ffunc( float, float ); > >Since Borland claims that both declaration styles are supported, it >seems to me that both should work. I experimented with variations of the sample program [which I deleted above]. The bug appears to be that Turbo C does not widen the float parameters in the old-style declaration to doubles. If the old-style declaration is changed to declare the parameters as doubles, the program works fine. When the compiler gets a function without a prototype, it has to assume that we are using old-style code, in which all parameters are widened just as in an arithmetic expression, i.e. char -> int, float -> double, etc. Thus, when compiling the function call, the float parameters are widened to doubles. Since these widenings occur in the function calls, the corresponding widening must be performed on the function definition: char parameters are actually ints, floats are actually doubles, etc. I checked old-style char parameters, and they worked correctly, but the old-style floats don't seem to be widened to doubles. Thus the two float parameters in the sample program are actually accessing the two halves of *one* of the parameters passed in--no wonder you get garbage values! The workarounds I see are: 1. use prototypes and new-style definitions only 2. manually widen floats to doubles in old-style parameter list definitions -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ARPA: RALF@B.GP.CS.CMU.EDU USnail: Ralf Brown AT&T: (412) 268-3053 (school) Computer Science Department Carnegie-Mellon University DISCLAIMER? Who ever said I claimed anything? Pittsburgh, PA 15213 "I do not fear computers. I fear the lack of them..." -- Isaac Asimov
psc@lznv.ATT.COM (Paul S. R. Chisholm) (07/23/87)
In article <3320030@hpsrlc.HP.COM>, darrylo@hpsrlc.UUCP writes: > In comp.sys.ibm.pc, kmh@ihlpm.ATT.COM (Kirk Hoyer) writes: > > Paul Chisholm correctly pointed out to me that, according to K & R > > section 2.7, floats are cast to doubles when used as function > > arguments. (I should note that the "cc" compiler on the large UNIX > > system I use at work was able to handle the program correctly, even > > though floats and double are different sizes.) (Maybe floats *are* doubles on your large system???) > I've heard that Turbo C WILL pass a float as a float (NOT as a double) > if function prototyping is used. Yes, indeed. If you'll remember, Kirk's program worked with prototypes, but not without them. > Is this ANSI C??? > -- Darryl Okahata, hplabs!hpcea!hpsrla!darrylo, CompuServe: 75206,3074 Yes (and C++, where function prototypes came from). -Paul S. R. Chisholm, UUCP {ihnp4,cbosgd,allegra,vax135,mtune}!lznv!psc AT&T Mail !psrchisholm, Internet psc@lznv.att.com I'm not speaking for my employer, I'm just speaking my mind.
kmh@ihlpm.ATT.COM (Kirk Hoyer) (07/24/87)
In article <1110@lznv.ATT.COM>, psc@lznv.ATT.COM (Paul S. R. Chisholm) writes: > In comp.sys.ibm.pc, kmh@ihlpm.ATT.COM (Kirk Hoyer) writes: > > Paul Chisholm correctly pointed out to me that, according to K & R > > section 2.7, floats are cast to doubles when used as function > > arguments. (I should note that the "cc" compiler on the large UNIX > > system I use at work was able to handle the program correctly, even > > though floats and double are different sizes.) > (Maybe floats *are* doubles on your large system???) Floats are not doubles on the large UNIX system where I work. This problem is indeed a bug in Turbo C (and is recognized as such by Borland). They claim to be working on a fix. The reason it is a bug (as was pointed out to me by another netlander): "C convers all float actual parameters to double, so formal parameters declared float have their declaration adjusted to read double." (K&R, C Reference Manual, section 10.1) Turbo C apparently adheres to the first part of this statement, but not the second part. Kirk Hoyer
ccs016@ucdavis.UUCP (Patrick Tully) (08/03/87)
I've started using Turbo C recently. I've only glanced at the manual so I may have missed this. My question is what key do I hit to stop a endless loop. I've tried all the normal ones, break, escape, control break, etc ... but nothing. I have been writing many programs using rom-bios interupts, I don't know if this is what did it. The basic problem is when I hit a endless loop I can't get out, only by rebooting. Patrick Tully pstully@ucdavis
darrylo@hpsrlc.HP.COM (Darryl Okahata) (08/04/87)
In comp.sys.ibm.pc, ccs016@ucdavis.UUCP (Patrick Tully) writes: > I've started using Turbo C recently. I've only glanced at the manual so I may > have missed this. My question is what key do I hit to stop a endless loop. I've > tried all the normal ones, break, escape, control break, etc ... but nothing. > > I have been writing many programs using rom-bios interupts, I don't know if > this is what did it. The basic problem is when I hit a endless loop I can't get > out, only by rebooting. > > Patrick Tully > pstully@ucdavis > ---------- The control-C/Break (control-Break) only works if you use DOS calls, not ROM BIOS calls. The reason for this is that DOS and only DOS checks to see if the user has hit control-C/Break. The ROM BIOS doesn't do jack diddly squat (except for setting a flag). Also, unless you execute the "BREAK ON" command from command.com, DOS will only check for a control-C/Break when DOS sends a character to the screen; with BREAK ON, DOS will check for a control-C/Break every time a DOS call is made. In short, if your program is in an infinite loop and does not make any DOS calls while in the loop, you're out of luck (unless you have special software which allows you to break out of a program and return to DOS, like the Periscope debugger). If your program is in an infinite loop and does make DOS calls, you can only break out if you've executed the "BREAK ON" command or are making a DOS console output call. -- Darryl Okahata {hplabs!hpcea!, hpfcla!} hpsrla!darrylo CompuServe: 75206,3074 Disclaimer: the above is the author's personal opinion and is not the opinion or policy of his employer or of the little green men that have been following him all day.