float.h and math.h

D

David Wade

Folks,
Well I am still dabling in the mire of math.h and getting on reasonably
well. A couple of questions.

Firstly when defining some of the extreme values in the many bits of code
seem to use "extern" definitions of various types. Is it OK to do something
like this in float.h:-

extern _ex_dbl_vals[3];
DBL_MAX _ex_dbl_vals[1];

and then have an assembler table that sets up _ex_dbl_vals, or does it have
to go via a function?

Secondly, is NAN a required value. I know GCC is not "gospel" but I see that
the IBM 370 parts assume that NAN does not exist on this architecture? And
if there is not a natural NAN would isnan() always return 0?

Dave.
 
T

Thad Smith

David said:
Firstly when defining some of the extreme values in the many bits of code
seem to use "extern" definitions of various types. Is it OK to do something
like this in float.h:-

extern _ex_dbl_vals[3];
DBL_MAX _ex_dbl_vals[1];

I assume you know that it is the implementor's responsibility, not the
computer user to do this. For the second line, do you mean
#define DBL_MAX _ex_dbl_vals[1]
?

To answer your question, no, that is not conforming because DBL_MAX must
be a constant expression, which that is not. Specifically, the compiler
must be able to access the value.
Secondly, is NAN a required value.

Not in Standard C. Its behavior is specified, but it is optional.
 
D

David Wade

Thad Smith said:
David said:
Firstly when defining some of the extreme values in the many bits of code
seem to use "extern" definitions of various types. Is it OK to do something
like this in float.h:-

extern _ex_dbl_vals[3];
DBL_MAX _ex_dbl_vals[1];

I assume you know that it is the implementor's responsibility, not the
computer user to do this.

Yes I have my implemtors hat on ...
For the second line, do you mean
#define DBL_MAX _ex_dbl_vals[1]
?

I think I meant

extern double ex_dbl_vals[3];
#define DBL_MAX ex_dbl_vals[1];

To answer your question, no, that is not conforming because DBL_MAX must
be a constant expression, which that is not. Specifically, the compiler
must be able to access the value.

If thats true most of the float.h files I have looked at are non-complient.
The standard says (of float.h):-

"FLT_RADIX shall be a constant expression suitable for use in #if
preprocessing directives; all other values need not be constant
expressions."
Not in Standard C. Its behavior is specified, but it is optional.

Thats one thing I don't need to do then....
 
R

Robert Gamble

David said:
Thad Smith said:
David said:
Firstly when defining some of the extreme values in the many bits of code
seem to use "extern" definitions of various types. Is it OK to do something
like this in float.h:-

extern _ex_dbl_vals[3];
DBL_MAX _ex_dbl_vals[1];

I assume you know that it is the implementor's responsibility, not the
computer user to do this.

Yes I have my implemtors hat on ...
For the second line, do you mean
#define DBL_MAX _ex_dbl_vals[1]
?

I think I meant

extern double ex_dbl_vals[3];
#define DBL_MAX ex_dbl_vals[1];

I certainly hope not, you are using a name that is reserved for the
user and your macro definition is broken.
If thats true most of the float.h files I have looked at are non-complient.
The standard says (of float.h):-

"FLT_RADIX shall be a constant expression suitable for use in #if
preprocessing directives; all other values need not be constant
expressions."

That was the C90 wording, C99 is more strict to allow values like
DBL_MAX to be used as initializers for static variables.
Thats one thing I don't need to do then....

Robert Gamble
 
D

David Wade

Robert Gamble said:
David said:
Thad Smith said:
David Wade wrote:> > code
seem to use "extern" definitions of various types. Is it OK to do

Firstly when defining some of the extreme values in the many bits of
something
like this in float.h:-

extern _ex_dbl_vals[3];
DBL_MAX _ex_dbl_vals[1];

I assume you know that it is the implementor's responsibility, not the
computer user to do this.

Yes I have my implemtors hat on ...
For the second line, do you mean
#define DBL_MAX _ex_dbl_vals[1]
?

I think I meant

extern double ex_dbl_vals[3];
#define DBL_MAX ex_dbl_vals[1];

I certainly hope not, you are using a name that is reserved for the
user and your macro definition is broken.

Ooops, I meant _EX...
That was the C90 wording, C99 is more strict to allow values like
DBL_MAX to be used as initializers for static variables.

So how do more modern ".h" files get round this?. Even if I do somthing link
this:-

typedef union {unsigned short _Shrt [4]; double _Dbl[4];}_DblShrt;
const _DblShrt _FltMax = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
#define DBL_MAX (_FltMax._Dbl)

GCC 331 won't let me use DBL_MAX to init storage.
 
R

Robert Gamble

David said:
Robert Gamble said:
David said:
David Wade wrote:> > code
seem to use "extern" definitions of various types. Is it OK to do

Firstly when defining some of the extreme values in the many bits of
something
like this in float.h:-

extern _ex_dbl_vals[3];
DBL_MAX _ex_dbl_vals[1];

I assume you know that it is the implementor's responsibility, not the
computer user to do this.

Yes I have my implemtors hat on ...

For the second line, do you mean
#define DBL_MAX _ex_dbl_vals[1]
?

I think I meant

extern double ex_dbl_vals[3];
#define DBL_MAX ex_dbl_vals[1];

I certainly hope not, you are using a name that is reserved for the
user and your macro definition is broken.

Ooops, I meant _EX...
That was the C90 wording, C99 is more strict to allow values like
DBL_MAX to be used as initializers for static variables.

So how do more modern ".h" files get round this?.

Something like:
#define DBL_MAX 1.7976931348623157e+308
or
#define DBL_MAX 0X1.fffffffffffffP1023
Even if I do somthing link this:-
typedef union {unsigned short _Shrt [4]; double _Dbl[4];}_DblShrt;
const _DblShrt _FltMax = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
#define DBL_MAX (_FltMax._Dbl)
Yuck.

GCC 331 won't let me use DBL_MAX to init storage.

That's because it's not a constant expression.

Robert Gamble
 
D

David Wade

Robert Gamble said:
David said:
Robert Gamble said:
David Wade wrote:
David Wade wrote:> > code
seem to use "extern" definitions of various types. Is it OK to do

Firstly when defining some of the extreme values in the many
bits of
something
like this in float.h:-

extern _ex_dbl_vals[3];
DBL_MAX _ex_dbl_vals[1];

I assume you know that it is the implementor's responsibility, not the
computer user to do this.

Yes I have my implemtors hat on ...

For the second line, do you mean
#define DBL_MAX _ex_dbl_vals[1]
?

I think I meant

extern double ex_dbl_vals[3];
#define DBL_MAX ex_dbl_vals[1];

I certainly hope not, you are using a name that is reserved for the
user and your macro definition is broken.

Ooops, I meant _EX...
To answer your question, no, that is not conforming because
DBL_MAX
must
be a constant expression, which that is not. Specifically, the compiler
must be able to access the value.

If thats true most of the float.h files I have looked at are non-complient.
The standard says (of float.h):-

"FLT_RADIX shall be a constant expression suitable for use in #if
preprocessing directives; all other values need not be constant
expressions."

That was the C90 wording, C99 is more strict to allow values like
DBL_MAX to be used as initializers for static variables.

So how do more modern ".h" files get round this?.

Something like:
#define DBL_MAX 1.7976931348623157e+308
or
#define DBL_MAX 0X1.fffffffffffffP1023

The hex floats are "new" in C99 aren't they.....
Even if I do somthing link this:-
typedef union {unsigned short _Shrt [4]; double _Dbl[4];}_DblShrt;
const _DblShrt _FltMax = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
#define DBL_MAX (_FltMax._Dbl)
Yuck.

GCC 331 won't let me use DBL_MAX to init storage.

That's because it's not a constant expression.

As opposed to being a constant value? This stuff gets yukier the more I look
at it...
And as GCC 331 is still C89 I guess that the sort of fudges I am using above
will have to stay....
Robert Gamble

Thanks for your input,
Dave.
 
R

Robert Gamble

David said:
Robert Gamble said:
David said:
David Wade wrote:
David Wade wrote:> > code
seem to use "extern" definitions of various types. Is it OK to do

Firstly when defining some of the extreme values in the many bits of

something
like this in float.h:-

extern _ex_dbl_vals[3];
DBL_MAX _ex_dbl_vals[1];

I assume you know that it is the implementor's responsibility, not the
computer user to do this.

Yes I have my implemtors hat on ...

For the second line, do you mean
#define DBL_MAX _ex_dbl_vals[1]
?

I think I meant

extern double ex_dbl_vals[3];
#define DBL_MAX ex_dbl_vals[1];

I certainly hope not, you are using a name that is reserved for the
user and your macro definition is broken.


Ooops, I meant _EX...


To answer your question, no, that is not conforming because DBL_MAX
must
be a constant expression, which that is not. Specifically, the
compiler
must be able to access the value.

If thats true most of the float.h files I have looked at are
non-complient.
The standard says (of float.h):-

"FLT_RADIX shall be a constant expression suitable for use in #if
preprocessing directives; all other values need not be constant
expressions."

That was the C90 wording, C99 is more strict to allow values like
DBL_MAX to be used as initializers for static variables.


So how do more modern ".h" files get round this?.

Something like:
#define DBL_MAX 1.7976931348623157e+308
or
#define DBL_MAX 0X1.fffffffffffffP1023

The hex floats are "new" in C99 aren't they.....
Even if I do somthing link this:-
typedef union {unsigned short _Shrt [4]; double _Dbl[4];}_DblShrt;
const _DblShrt _FltMax = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
#define DBL_MAX (_FltMax._Dbl)
Yuck.

GCC 331 won't let me use DBL_MAX to init storage.

That's because it's not a constant expression.

As opposed to being a constant value?

Right, a const qualified type isn't a constant expression in C.
This stuff gets yukier the more I look
at it...
And as GCC 331 is still C89 I guess that the sort of fudges I am using above
will have to stay....
<< and I am stuck with 331 because I am using an obsoleted platform>>>

gcc 3.3.1 supports much of the C99 Standard. In gcc's float.h, DBL_MAX
expands to __DBL_MAX__ which is a built-in macro expanding to (on my
system) 1.7976931348623157e+308. The only reason for this round-about
method (AKAIK) is portability, the same float.h can be used for
multiple platforms without change. What this means though is that the
float.h provided by gcc won't work with a preprocessor that doesn't
define __DBL_MAX__ accordingly, the header is tied closely to the
compiler. What exactly are you trying to accomplish?

Robert Gamble
 
D

David Wade

Robert Gamble said:
David said:
Robert Gamble said:
David Wade wrote:
David Wade wrote:
David Wade wrote:> > code
seem to use "extern" definitions of various types. Is it OK
to
do
Firstly when defining some of the extreme values in the many bits of

something
like this in float.h:-

extern _ex_dbl_vals[3];
DBL_MAX _ex_dbl_vals[1];

I assume you know that it is the implementor's responsibility,
not
the
computer user to do this.

Yes I have my implemtors hat on ...

For the second line, do you mean
#define DBL_MAX _ex_dbl_vals[1]
?

I think I meant

extern double ex_dbl_vals[3];
#define DBL_MAX ex_dbl_vals[1];

I certainly hope not, you are using a name that is reserved for the
user and your macro definition is broken.


Ooops, I meant _EX...


To answer your question, no, that is not conforming because DBL_MAX
must
be a constant expression, which that is not. Specifically, the
compiler
must be able to access the value.

If thats true most of the float.h files I have looked at are
non-complient.
The standard says (of float.h):-

"FLT_RADIX shall be a constant expression suitable for use in #if
preprocessing directives; all other values need not be constant
expressions."

That was the C90 wording, C99 is more strict to allow values like
DBL_MAX to be used as initializers for static variables.


So how do more modern ".h" files get round this?.

Something like:
#define DBL_MAX 1.7976931348623157e+308
or
#define DBL_MAX 0X1.fffffffffffffP1023

The hex floats are "new" in C99 aren't they.....
Even if I do somthing link this:-
typedef union {unsigned short _Shrt [4]; double _Dbl[4];}_DblShrt;
const _DblShrt _FltMax = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
#define DBL_MAX (_FltMax._Dbl)

Yuck.

GCC 331 won't let me use DBL_MAX to init storage.

That's because it's not a constant expression.

As opposed to being a constant value?

Right, a const qualified type isn't a constant expression in C.
This stuff gets yukier the more I look
at it...
And as GCC 331 is still C89 I guess that the sort of fudges I am using above
will have to stay....
<< and I am stuck with 331 because I am using an obsoleted platform>>>

gcc 3.3.1 supports much of the C99 Standard. In gcc's float.h, DBL_MAX
expands to __DBL_MAX__ which is a built-in macro expanding to (on my
system) 1.7976931348623157e+308. The only reason for this round-about
method (AKAIK) is portability, the same float.h can be used for
multiple platforms without change. What this means though is that the
float.h provided by gcc won't work with a preprocessor that doesn't
define __DBL_MAX__ accordingly, the header is tied closely to the
compiler. What exactly are you trying to accomplish?
/* you may want to skip this */
What I REALLY want to acomplish is to provide a REXX interpreter on the
VM/370 (old free version of IBM Mainframe OS)under the Hercules emulator, to
make it more like modern versions which as an individual I can't license.
There are a couple free REXX interpreters, but of course they are written in
"C"....
/* end of epehemera */

So I need a "C" compiler that will, at least cross compile to the I370 (not
370/XA, ESA, I390 or X/Series) architecture and old (pre 4.0) GCC's will do
this. However there were some issues with floating point in the original
port, so it is rather lacking in the FP area. In particular math.h and
float.h are somewhat minimal. I was using some one elses library and
became a sad bunny when I looked in float.h and found it was basically the
minimum spec from the ANSI standard.As I370 uses HEX floating point its was
somewhat broken. I have fixed most of it but I am having problems with
DBL_MIN and DBL_EPSILON. GCC seems to underflow and puts "0.0e0" in the
assember output when compiling the decimal equivalent. I don't feel strong
enough to delve into GCCs "real.c" again....

I do have a copy of "The Standard "C" Library" but in some ways that makes
things worse because I don't want to infringe copyright. (also Hastings and
Cody & Waite)....
Robert Gamble

Thanks for your interest,
Dave.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,183
Messages
2,570,967
Members
47,517
Latest member
Andres38A1

Latest Threads

Top