[comp.sys.apple2] Help with Floats in Hyper C

bill@braille.uwo.ca (Bill Carss) (06/16/91)

I am just beginning to learn C.  I am using K&R and have FINALLY started
to work my way through the text as I learn the language.  The float 
problem cropped up in the thrid program discussed.  It is simply a 
program to convert fahrenheit temperatures to celsius and to get a little
more accuracy than int's provide, they suggest declaring fahr and celsius
as ftype float.

The program is as follows:

#include <stdio.h>  /* I changed the name of std.h for compatability */
#include <fp.h>

/*  Convert Fahrenheit to celsius in the range
    0, 20, ..., 300                             */

main()
  {
    float fahr, celsius;
    int lower, upper, step;

    lower = 0;
    upper = 300;
    step = 20;
 
    fahr = lower;
    while (fahr <= upper)  {
       celsius = (5.0/9.0) * (fahr-32);
       printf("%3.0f %6.1f \n, fahr, celsius");
       fahr = fahr + step;
    }
 }

I typed in the above program and got an error message telling me that the 
"fahr = lower;" line was not a pointer.

I have a friend is is an experienced C programmer (he has a couple of 
commercial packages to his name) and he suggested casting <?> in the form

fahr = (float)lower;

This resulted in an error message relating to the while statement such that
it was invalid.

I have done some reading of the documentation that I have and have found
nothing much to do with "float"s other than the fact that they are not ever
defined (that I can find) and it is necessary to convert them to other
things to use them.  There are functions like cvxtoi (and the 
reverse), but I thought PPF should take care of that for me.

Any halp anyone can give me would be greatly appreciated.
-- 
Bill Carss
bill@braille.uwo.ca

ericmcg@pnet91.cts.com (Eric Mcgillicuddy) (06/22/91)

>    float fahr, celsius;
>    int lower, upper, step;
>
>    lower = 0;
>    upper = 300;
>    step = 20;
>
>    fahr = lower;
>    while (fahr <= upper)  {
>       celsius = (5.0/9.0) * (fahr-32);
>       printf("%3.0f %6.1f \n, fahr, celsius");
>       fahr = fahr + step;
>    }
>Bill Carss
>bill@braille.uwo.ca

The problem is that you are comparing apples to cats, although there may be
some similarities from certain perspectives, these similarities may not be
what you are interested in testing. 

Two things to note. Floats are stored in a different format from Ints. I think
0 is equivalent to both, but that is the end of all similarities. Certain
compilers automatically coerce variables from one type to another, HyperC does
not. The programmer must explicitly tell the compiler to test Ints as Floats
doing the neccessary conversions beforehand to make the comparison meaning
full. Casting lets the compiler know what you want to do.

        fahr = (float) lower;
        while (fahr <= (float) upper {
                do_stuff();
                fahr = fahr + (float) step;
        }

This should do the trick and is more portable (although still not good C code)
than that in K&R's book.

UUCP: bkj386!pnet91!ericmcg
INET: ericmcg@pnet91.cts.com

gwyn@smoke.brl.mil (Doug Gwyn) (06/23/91)

In article <863@generic.UUCP> ericmcg@pnet91.cts.com (Eric Mcgillicuddy) writes:
>>       printf("%3.0f %6.1f \n, fahr, celsius");
>>bill@braille.uwo.ca
>Certain compilers automatically coerce variables from one type to another,
>HyperC does not.

While it may be true that Hyper C does not correctly implement a translator
for programming language C, perhaps the real problem is the totally
incorrect printf() invocation as quoted above.

cs4w+@andrew.cmu.edu (Charles William Swiger) (06/23/91)

>Two things to note. Floats are stored in a different format
>from Ints. I think 0 is equivalent to both, but that is the
>end of all similarities. Certain compilers automatically
>coerce variables from one type to another, HyperC does not.
>The programmer must explicitly tell the compiler to test
>Ints as Floats doing the neccessary conversions beforehand
>to make the comparison meaning full. Casting lets the
>compiler know what you want to do.  This should do the
>trick and is more portable (although still not good C code)
>than that in K&R's book.

Your comments about what is required to produce legal C code are simply
not correct...you can check with either K&R, the ANSI C specification,
or various other C reference materials.  You should not need to convert
a float to an int in an assignment, nor should you have to convert an
int to a float in order to perform floating point arithmetic.  That you
have to in order to produce executable code for Hyper C means that Hyper
C is a seriously deficient implementation of the language.  

Unfortunately, the size requirements for a correct C compiler are
(admittedly) fairly extensive:

Required programs and size in kilobytes, for the DECstation 3100 C compiler:

cc     =  86  C compiler
ccom   = 278  C front end
cpp    =  49  macro pre-processor
ld     = 213  loader


High performance code optimizers (optional):
ugen   = 331  ucode generator
ujoin  =  73  binary ucode and symbol table joiner
umerge = 119  procedure integrator
uopt   = 454  global ucode optimizer
usplit =  57  binary ucode and symbol table splitter

Grand total: 1.66 megabytes

>Eric Mcgillicuddy@pnet91.cts.com


-- Charles William Swiger
    cs4w+@andrew.cmu.edu

ericmcg@pnet91.cts.com (Eric Mcgillicuddy) (06/23/91)

>Your comments about what is required to produce legal C code are simply
>not correct...you can check with either K&R, the ANSI C specification,
>or various other C reference materials.  You should not need to convert
>a float to an int in an assignment, nor should you have to convert an
>int to a float in order to perform floating point arithmetic.  That you
>have to in order to produce executable code for Hyper C means that Hyper
>C is a seriously deficient implementation of the language.
>-- Charles William Swiger
>    cs4w+@andrew.cmu.edu

I am not referring to legal C code, I am referring to HyperC C code. Most C
compilers will adjust the variables on the fly, however explicitly casting
them to identical types should not affect the compiler, and it has the added
advantage of letting everyone know you know what is going on. 

HyperC is intended to use integer math only, the memory cost for floating
point is horrendous. The basic version has no FP support whatsoever, however a
floating point library was added later. Note that the compiler was not
changed, only the preporcessor, so floats must be treated explicitly as some
combination of more basic types, strings in this case I believe.

It should be possible to write HyperC code that is portable to any other C
compiler, but the reverse is not neccessarily true. 

UUCP: bkj386!pnet91!ericmcg
INET: ericmcg@pnet91.cts.com

bill@braille.uwo.ca (Bill Carss) (06/23/91)

gwyn@smoke.brl.mil (Doug Gwyn) writes:

>In article <863@generic.UUCP> ericmcg@pnet91.cts.com (Eric Mcgillicuddy) writes:
>>>       printf("%3.0f %6.1f \n, fahr, celsius");
>>>bill@braille.uwo.ca
>>Certain compilers automatically coerce variables from one type to another,
>>HyperC does not.

>While it may be true that Hyper C does not correctly implement a translator
>for programming language C, perhaps the real problem is the totally
>incorrect printf() invocation as quoted above.

Mr. Gwyn points out (as many have) that my printf() statement was wrong.  As I
have mentioned in subsequent posts (and letters to various writers), I made a 
typing mistake nothing more.  Anyway, be that as it may, that is NOT
the major source of problems for this program in Hyperc.

Fortunately a solution has been found and I shall list it now.


#include <std.h>
#include <fp.h>

/*  Convert Fahrenheit to celsius in the range
    0, 20, ..., 300                             */

/*  ported by Andy Werner from an example in C PROGRAMMING LANGUAGE
    by Kernighan and Ritchie to HyperC and its SANE extension       */

main()
  {
    EXTENDED  temp1;
    INT lower, upper, fahr, step, temp2;
    TEXT buf[80];

    lower = 0;
    upper = 300;
    step = 20;

        fahr = lower; while (fahr <= upper) {
        EXTENDED f1 = Extended(5.0);
        EXTENDED f2 = Extended(9.0);
        EXTENDED subtrahend = Extended(32.0);
        temp2 = fahr;
        cvitox(temp1, temp2);
        fsubx(temp1, subtrahend);
        fdivx(f1, f2);
        fmulx(f1, temp1);
        fptostr(buf, f1, 'x', 6, NO);
        printf("fahr = %d, celsius = %s \n", fahr, buf);
        fahr = fahr + step;
    }
 }


This program works!!  My thanks to Andy Warner for his coding expertise.

As far as Mr. Gwyn's comment is concerned well .... obviously he knows as much
(or as little) about HyperC as I do.
-- 
Bill Carss
bill@braille.uwo.ca