[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::decc

Title:DECC
Notice:General DEC C discussions
Moderator:TLE::D_SMITHNTE
Created:Fri Nov 13 1992
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:2212
Total number of notes:11045

2113.0. "atof question/problem??" by CSC32::E_VAETH (Suffering from temporary brain cramp, stay tuned) Thu Mar 06 1997 12:30

A customer feels that the atof function is misbehaving on 
OpenVMS Alpha.  He feels that atof results in a value that
is not HUGE_VAL.  He submitted the following example to 
demonstrate what he feels is incorrect output.

This is what he sees:

$ cc /float=ieee_float /ieee_mode=denorm_results  tatof
$ link tatof
$ run tatof
atof_in: 2.209e309, produces ERANGE
atof_in: 2.209e309, results in 1.79769313486231570000e+308

I believe that the value being passed is outside a double
range, so one would expect an overflow.  
I see what he wants if I do not specify the IEEE float
option:

$ cc tatof
$ link tatof
$ run tatof
atof_in: 2.209e309, produces ERANGE
atof_in: 2.209e309, results in HUGH_VAL

Is this expected behavior??

Thanks,

Elin

#include <signal.h>
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h> /* needed for EXIT_SUCCESS */
#include <errno.h>
#include <errnodef.h>
#include <fp.h>

int main()
{
    char * atof_in="2.209e309";
    double atof_out;

    atof_out=atof(atof_in);
    if (errno == ERANGE) {
	printf("atof_in: %s, produces ERANGE\n", atof_in);
	if (atof_out == HUGE_VAL) {
	    printf("atof_in: %s, results in HUGH_VAL\n", atof_in);
	} else {
	    printf("atof_in: %s, results in %1.20e\n", atof_in, atof_out);
	}
    }

    if (errno == EINVAL) {
	printf("atof_in: %s, produces EINVAL\n", atof_in);
    }

    return EXIT_SUCCESS;
}

T.RTitleUserPersonal
Name
DateLines
2113.1Problem appears to be atof not producing InfinityCXXC::REPETERich Peterson 381-1802 ZKO2-3/N30Thu Mar 06 1997 16:587
As always, it helps to specify the compiler version and OS version.
But with DEC C V5.5-002 on OpenVMS Alpha V6.2-1H3, what happens is
that compiling with the specified qualifiers causes HUGE_VAL to be
#defined to decc$gt_dbl_infinity, which is a double variable containing
an IEEE Infinity bit pattern.  The atof function, however, appears to
be returning the largest representable finite double value instead of
Infinity.
2113.2certainly a bug, where?TAVENG::BORISBoris Gubenko, ISEThu Mar 06 1997 18:25106
  First of all, both ANSI C and XPG4 specify atof behavior on error as
  undefined, so, generally, speaking, the customer should not rely on any
  errno or HUGE_VAL when using atof.

  ANSI C says:

	The functions atof, atoi and atol need not affect the value of the
	integer expression errno on an error. If the value of the result
	cannot be represented, the behavior is undefined.

  The same can be found in XPG4.

  Unfortunately, :-) the DEC C RTL implementation of atof acts just as a
  wrapper to strtod. In contrast to atof, the strtod *must* return plus or
  minus HUGE_VAL and set errno to ERANGE if the value to be converted is
  outside the range of representable values.

  The strtod - like behavior on error is documented in the description of
  atof in the DEC C RTL Manual, so the program in .0 must behave the same
  for the default G_FLOAT floating point and for IEEE floating point.

  Actually, what happened is that while building the CRTL, the IEEE-flavour
  of atof() routine is compiled with /FLOAT=IEEE_FLOAT without /IEEE qualifier,
  i.e. in default /IEEE=FAST IEEE mode.

  The HUGE_VAL is defined in <math.h> as follows:

/*
**  Define HUGE_VAL
*/
#if __G_FLOAT
#   define HUGE_VAL 8.988465674311578540726371186585e+307
#   define __MAXFLOAT 1.7014117e+38f
#elif __IEEE_FLOAT
#   ifdef _IEEE_FP
       extern double decc$gt_dbl_infinity;
#      define HUGE_VAL decc$gt_dbl_infinity
#   else
#      define HUGE_VAL 1.7976931348623158e+308
#   endif
#   define __MAXFLOAT 3.40282347e+38f
#else
#   ifdef __ALPHA
#      define HUGE_VAL 1.70141183460469213e+38    
#   else 
#      define HUGE_VAL 1.70141183460469229e+38
#   endif
#   define __MAXFLOAT 1.7014117e+38f
#endif

  I have no idea why _IEEE_FP macro is not defined in /IEEE=FAST IEEE mode.
  The fact is that _IEEE_FP macro is defined for /IEEE_MODE=DENORM_RESULT
  and is not defined for default /IEEE=FAST mode, so for IEEE-flavour of atof() 
  function the HUGE_VAL is 1.7976931348623158e+308. The function detects
  overflow, sets errno to ERANGE and returns its HUGE_VAL, but for the test
  program in .0, compiled with /IEEE_MODE=DENORM_RESULT, the HUGE_VAL is
  decc$gt_dbl_infinity and these two HUGE_VALues are different.

  I'm not sure if this a bug in the header, in the compiler or in the DEC C RTL.

  Boris

X.C
===

#if __IEEE_FLOAT
#   ifdef _IEEE_FP
       extern double decc$gt_dbl_infinity;
#      define HUGE_VAL decc$gt_dbl_infinity
#   else
#      define HUGE_VAL 1.7976931348623158e+308
#   endif
#   define __MAXFLOAT 3.40282347e+38f
#endif

$ cc/ver/noobj _nl0:
DEC C V5.0-003 on OpenVMS Alpha V6.2-1H1

$ cc/float=ieee/lis/show=all x.c
                                Source Listing                   7-MAR-1997 01:13:26    DEC C V5.0-003                      Page   1
                                                                 7-MAR-1997 01:12:12    ENG17:[BORIS]X.C;3

	      1 #if __IEEE_FLOAT
	      2 #   ifdef _IEEE_FP
       X      3        extern double decc$gt_dbl_infinity;
       X      4 #      define HUGE_VAL decc$gt_dbl_infinity
       X      5 #   else
	      6 #      define HUGE_VAL 1.7976931348623158e+308
	      7 #   endif
	      8 #   define __MAXFLOAT 3.40282347e+38f
	      9 #endif

$ cc/float=ieee/ieee=denorm/lis/show=all x.c

                                Source Listing                   7-MAR-1997 01:14:23    DEC C V5.0-003                      Page   1
                                                                 7-MAR-1997 01:12:12    ENG17:[BORIS]X.C;3

	      1 #if __IEEE_FLOAT
	      2 #   ifdef _IEEE_FP
	      3        extern double decc$gt_dbl_infinity;
	      4 #      define HUGE_VAL decc$gt_dbl_infinity
	      5 #   else
       X      6 #      define HUGE_VAL 1.7976931348623158e+308
       X      7 #   endif
	      8 #   define __MAXFLOAT 3.40282347e+38f
	      9 #endif
2113.3entered into CRTL_INTERNALTAVENG::BORISBoris Gubenko, ISEThu Mar 06 1997 18:345
  This is being tracked in crtl internal bug tracking system as problem
  # 1694.

  Boris 
2113.46.2, DEC C 5.0?CSC32::E_VAETHSuffering from temporary brain cramp, stay tunedThu Mar 06 1997 19:428
    Sorry - I did forget the version info.  The customer is running on
    OpenVMS Alpha V6.2.  I believe he is running DEC C 5.0.  However, I
    pointed out that any testing would be against the current supported
    release.  
    
    Thank you for the great explanations.  
    
    -elin
2113.5Needs to vary at run-timeWIBBIN::NOYCEPulling weeds, pickin&#039; stonesFri Mar 07 1997 07:5811
Boris, I think this is an example where the CRTL needs to be sensitive to
the mode in which the caller is compiled.  If the caller is /IEEE=FAST,
it can't cope with infinities (or denorms), and you should return the value
you're returning today.  If the caller is /IEEE=DENORM, you should return
infinity for overflow, and you should be able to return denorms too.

There are flags in the procedure descriptor that tell what mode a routine
was compiled in.  It looks as if strtod needs to look at these flags when
it encounters an exceptional condition.  atod needs to be compiled in the
mode that says "look at my caller's mode instead of mine."  For more
information on how to do all this, talk to Jeff RTL::Arnold in the DPML group.
2113.6thanksTAVENG::BORISBoris Gubenko, ISEFri Mar 07 1997 08:325
 Rep to .-1

 Thank you very much,

 Boris