NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.

To learn about what's going on, see About the Archive Site.

question about float to int type conversion...

NOTE: The netcdf-hdf mailing list is no longer active. The list archives are made available for historical reasons.

Howdy HDFers!

I sent this question to Quincey last week, but he hasn't
replied. Perhaps someone left his office door unlocked and he wandered
off. ;-)

I'm writing some floats to ints, and the floats are all smaller or
larger than a 4 byte signed int allows, so I expect them all to
overflow. However, they don't.

The output below shows the problem. Isn't it true that when I try to
write these floats to an int, I should get an overflow each time?

   float float_data_out2[DIM1_LEN] = {(float)INT_MIN - 1.0, (float)INT_MIN - 
1.0, (float)INT_MAX + 129.0};

That is, writing the above array should call my exception function
three times, but it is only called once, for the last value (and if
that is +128, it's not called for that either).

I don't understand this behavior. I am getting INT_MIN from limits.h:
/* Minimum and maximum values a `signed int' can hold.  */
#  define INT_MIN       (-INT_MAX - 1)
#  define INT_MAX       2147483647

So why doesn't it generate an overflow?

Thanks!

Ed

output:

*** Checking HDF5 data type conversions.
*** creating test file...ok.
*** reading int dataset as floats...ok.
*** reading float dataset as uchars...ok.
*** writing out of range floats to int dataset...
float_data_out2[0]=-2147483648.000000
(int)float_data_out2[0]=-2147483648
float_data_out2[1]=-2147483648.000000
(int)float_data_out2[1]=-2147483648
float_data_out2[2]=2147483904.000000
(int)float_data_out2[2]=-2147483648
overflow_count=1
unexpected result, tst_h_converts.c, line: 546
1 failures
1 errors detected! Sorry!

tst_h_converts.c:

/* This is part of the netCDF package.
   Copyright 2005 University Corporation for Atmospheric Research/Unidata
   See COPYRIGHT file for conditions of use.

   Test HDF5 file code. These are not intended to be exhaustive tests,
   but they use HDF5 the same way that netCDF-4 does, so if these
   tests don't work, than netCDF-4 won't work either.

   $Id: tst_h_converts.c,v 1.2 2005/06/23 01:07:12 ed Exp $
*/
#include "tests.h"
#include <limits.h>

#define FILE_NAME "tst_h_converts.h5"
#define GRP_NAME "my_group"
#define INT_VAR_NAME "int_var"
#define FLOAT_VAR_NAME "float_var"
#define SCHAR_VAR_NAME "schar_var"
#define DIM1_LEN 3

/* This function is called when there is an overflow in a read/write
 * operation. Pass the fill value in as user_data. */
H5T_conv_ret_t
except_func(int except_type, hid_t src_id, hid_t dst_id, 
            void *src_buf, void *dst_buf, void *user_data)
{
   /*printf("except_func: except_type %d\n", except_type);*/

   if(except_type == H5T_CONV_EXCEPT_RANGE_HI ||
      except_type == H5T_CONV_EXCEPT_RANGE_LOW)
   {
      if (H5Tequal(dst_id, H5T_STD_I8BE) > 0 ||
          H5Tequal(dst_id, H5T_STD_I8LE) > 0)
      {
         if (H5Tequal(src_id, H5T_STD_I8BE) > 0 ||
             H5Tequal(src_id, H5T_STD_I8LE) > 0)
            *(signed char *)dst_buf = *(signed char *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U8BE) ||
                  H5Tequal(src_id, H5T_STD_U8LE) > 0)
            *(signed char *)dst_buf = (unsigned char)*(float *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I16BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I16LE) > 0)
            *(signed char *)dst_buf = *(signed short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U16BE) ||
                  H5Tequal(src_id, H5T_STD_U16LE) > 0)
            *(signed char *)dst_buf = *(unsigned short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I32BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I32LE) > 0)
            *(signed char *)dst_buf = *(signed int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U32BE) ||
                  H5Tequal(src_id, H5T_STD_U32LE) > 0)
            *(signed char *)dst_buf = *(unsigned int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I64BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I64LE) > 0)
            *(signed char *)dst_buf = *(signed long long *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U64BE) ||
                  H5Tequal(src_id, H5T_STD_U64LE) > 0)
            *(signed char *)dst_buf = *(unsigned long long *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F32BE) > 0 ||
                  H5Tequal(src_id, H5T_IEEE_F32LE) > 0)
            *(signed char *)dst_buf = *(float *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F64BE) ||
                  H5Tequal(src_id, H5T_IEEE_F64LE) > 0)
            *(signed char *)dst_buf = *(double *)src_buf;
         else
         {
            printf("Unknown type!\n");
            return H5T_CONV_UNHANDLED;
         }       
      }
      else if (H5Tequal(dst_id, H5T_STD_U8BE) ||
               H5Tequal(dst_id, H5T_STD_U8LE) > 0)
      {
         if (H5Tequal(src_id, H5T_STD_I8BE) > 0 ||
             H5Tequal(src_id, H5T_STD_I8LE) > 0)
            *(unsigned char *)dst_buf = *(signed char *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U8BE) ||
                  H5Tequal(src_id, H5T_STD_U8LE) > 0)
            *(unsigned char *)dst_buf = (unsigned char)*(float *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I16BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I16LE) > 0)
            *(unsigned char *)dst_buf = *(signed short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U16BE) ||
                  H5Tequal(src_id, H5T_STD_U16LE) > 0)
            *(unsigned char *)dst_buf = *(unsigned short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I32BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I32LE) > 0)
            *(unsigned char *)dst_buf = *(signed int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U32BE) ||
                  H5Tequal(src_id, H5T_STD_U32LE) > 0)
            *(unsigned char *)dst_buf = *(unsigned int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I64BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I64LE) > 0)
            *(unsigned char *)dst_buf = *(signed long long *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U64BE) ||
                  H5Tequal(src_id, H5T_STD_U64LE) > 0)
            *(unsigned char *)dst_buf = *(unsigned long long *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F32BE) > 0 ||
                  H5Tequal(src_id, H5T_IEEE_F32LE) > 0)
            *(unsigned char *)dst_buf = *(float *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F64BE) ||
                  H5Tequal(src_id, H5T_IEEE_F64LE) > 0)
            *(unsigned char *)dst_buf = *(double *)src_buf;
         else
         {
            printf("Unknown type!\n");
            return H5T_CONV_UNHANDLED;
         }       
      }
      else if (H5Tequal(dst_id, H5T_STD_I16BE) > 0 ||
               H5Tequal(dst_id, H5T_STD_I16LE) > 0)
      {
         if (H5Tequal(src_id, H5T_STD_I8BE) > 0 ||
             H5Tequal(src_id, H5T_STD_I8LE) > 0)
            *(short *)dst_buf = *(signed char *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U8BE) ||
                  H5Tequal(src_id, H5T_STD_U8LE) > 0)
            *(short *)dst_buf = (unsigned char)*(float *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I16BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I16LE) > 0)
            *(short *)dst_buf = *(signed short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U16BE) ||
                  H5Tequal(src_id, H5T_STD_U16LE) > 0)
            *(short *)dst_buf = *(unsigned short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I32BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I32LE) > 0)
            *(short *)dst_buf = *(signed int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U32BE) ||
                  H5Tequal(src_id, H5T_STD_U32LE) > 0)
            *(short *)dst_buf = *(unsigned int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I64BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I64LE) > 0)
            *(short *)dst_buf = *(signed long long *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U64BE) ||
                  H5Tequal(src_id, H5T_STD_U64LE) > 0)
            *(short *)dst_buf = *(unsigned long long *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F32BE) > 0 ||
                  H5Tequal(src_id, H5T_IEEE_F32LE) > 0)
            *(short *)dst_buf = *(float *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F64BE) ||
                  H5Tequal(src_id, H5T_IEEE_F64LE) > 0)
            *(short *)dst_buf = *(double *)src_buf;
         else
         {
            printf("Unknown type!\n");
            return H5T_CONV_UNHANDLED;
         }       
      }
      else if (H5Tequal(dst_id, H5T_STD_U16BE) ||
               H5Tequal(dst_id, H5T_STD_U16LE) > 0)
      {
         if (H5Tequal(src_id, H5T_STD_I8BE) > 0 ||
             H5Tequal(src_id, H5T_STD_I8LE) > 0)
            *(unsigned short *)dst_buf = *(signed char *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U8BE) ||
                  H5Tequal(src_id, H5T_STD_U8LE) > 0)
            *(unsigned short *)dst_buf = (unsigned char)*(float *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I16BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I16LE) > 0)
            *(unsigned short *)dst_buf = *(signed short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U16BE) ||
                  H5Tequal(src_id, H5T_STD_U16LE) > 0)
            *(unsigned short *)dst_buf = *(unsigned short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I32BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I32LE) > 0)
            *(unsigned short *)dst_buf = *(signed int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U32BE) ||
                  H5Tequal(src_id, H5T_STD_U32LE) > 0)
            *(unsigned short *)dst_buf = *(unsigned int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I64BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I64LE) > 0)
            *(unsigned short *)dst_buf = *(signed long long *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U64BE) ||
                  H5Tequal(src_id, H5T_STD_U64LE) > 0)
            *(unsigned short *)dst_buf = *(unsigned long long *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F32BE) > 0 ||
                  H5Tequal(src_id, H5T_IEEE_F32LE) > 0)
            *(unsigned short *)dst_buf = *(float *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F64BE) ||
                  H5Tequal(src_id, H5T_IEEE_F64LE) > 0)
            *(unsigned short *)dst_buf = *(double *)src_buf;
         else
         {
            printf("Unknown type!\n");
            return H5T_CONV_UNHANDLED;
         }       
      }
      else if (H5Tequal(dst_id, H5T_STD_I32BE) > 0 ||
               H5Tequal(dst_id, H5T_STD_I32LE) > 0)
      {
         if (H5Tequal(src_id, H5T_STD_I8BE) > 0 ||
             H5Tequal(src_id, H5T_STD_I8LE) > 0)
            *(int *)dst_buf = *(signed char *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U8BE) ||
                  H5Tequal(src_id, H5T_STD_U8LE) > 0)
            *(int *)dst_buf = (unsigned char)*(float *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I16BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I16LE) > 0)
            *(int *)dst_buf = *(signed short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U16BE) ||
                  H5Tequal(src_id, H5T_STD_U16LE) > 0)
            *(int *)dst_buf = *(unsigned short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I32BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I32LE) > 0)
            *(int *)dst_buf = *(signed int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U32BE) ||
                  H5Tequal(src_id, H5T_STD_U32LE) > 0)
            *(int *)dst_buf = *(unsigned int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I64BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I64LE) > 0)
            *(int *)dst_buf = *(signed long long *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U64BE) ||
                  H5Tequal(src_id, H5T_STD_U64LE) > 0)
            *(int *)dst_buf = *(unsigned long long *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F32BE) > 0 ||
                  H5Tequal(src_id, H5T_IEEE_F32LE) > 0)
            *(int *)dst_buf = *(float *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F64BE) ||
                  H5Tequal(src_id, H5T_IEEE_F64LE) > 0)
            *(int *)dst_buf = *(double *)src_buf;
         else
         {
            printf("Unknown type!\n");
            return H5T_CONV_UNHANDLED;
         }       
      }
      else if (H5Tequal(dst_id, H5T_STD_U32BE) ||
               H5Tequal(dst_id, H5T_STD_U32LE) > 0)
      {
         if (H5Tequal(src_id, H5T_STD_I8BE) > 0 ||
             H5Tequal(src_id, H5T_STD_I8LE) > 0)
            *(unsigned int *)dst_buf = *(signed char *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U8BE) ||
                  H5Tequal(src_id, H5T_STD_U8LE) > 0)
            *(unsigned int *)dst_buf = (unsigned char)*(float *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I16BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I16LE) > 0)
            *(unsigned int *)dst_buf = *(signed short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U16BE) ||
                  H5Tequal(src_id, H5T_STD_U16LE) > 0)
            *(unsigned int *)dst_buf = *(unsigned short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I32BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I32LE) > 0)
            *(unsigned int *)dst_buf = *(signed int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U32BE) ||
                  H5Tequal(src_id, H5T_STD_U32LE) > 0)
            *(unsigned int *)dst_buf = *(unsigned int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I64BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I64LE) > 0)
            *(unsigned int *)dst_buf = *(signed long long *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U64BE) ||
                  H5Tequal(src_id, H5T_STD_U64LE) > 0)
            *(unsigned int *)dst_buf = *(unsigned long long *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F32BE) > 0 ||
                  H5Tequal(src_id, H5T_IEEE_F32LE) > 0)
            *(unsigned int *)dst_buf = *(float *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F64BE) ||
                  H5Tequal(src_id, H5T_IEEE_F64LE) > 0)
            *(unsigned int *)dst_buf = *(double *)src_buf;
         else
         {
            printf("Unknown type!\n");
            return H5T_CONV_UNHANDLED;
         }       
      }
      else if (H5Tequal(dst_id, H5T_STD_I64BE) > 0 ||
               H5Tequal(dst_id, H5T_STD_I64LE) > 0)
      {
         if (H5Tequal(src_id, H5T_STD_I8BE) > 0 ||
             H5Tequal(src_id, H5T_STD_I8LE) > 0)
            *(signed long long *)dst_buf = *(signed char *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U8BE) ||
                  H5Tequal(src_id, H5T_STD_U8LE) > 0)
            *(signed long long *)dst_buf = (unsigned char)*(float *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I16BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I16LE) > 0)
            *(signed long long *)dst_buf = *(signed short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U16BE) ||
                  H5Tequal(src_id, H5T_STD_U16LE) > 0)
            *(signed long long *)dst_buf = *(unsigned short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I32BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I32LE) > 0)
            *(signed long long *)dst_buf = *(signed int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U32BE) ||
                  H5Tequal(src_id, H5T_STD_U32LE) > 0)
            *(signed long long *)dst_buf = *(unsigned int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I64BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I64LE) > 0)
            *(signed long long *)dst_buf = *(signed long long *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U64BE) ||
                  H5Tequal(src_id, H5T_STD_U64LE) > 0)
            *(signed long long *)dst_buf = *(unsigned long long *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F32BE) > 0 ||
                  H5Tequal(src_id, H5T_IEEE_F32LE) > 0)
            *(signed long long *)dst_buf = *(float *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F64BE) ||
                  H5Tequal(src_id, H5T_IEEE_F64LE) > 0)
            *(signed long long *)dst_buf = *(double *)src_buf;
         else
         {
            printf("Unknown type!\n");
            return H5T_CONV_UNHANDLED;
         }       
      }
      else if (H5Tequal(dst_id, H5T_STD_U64BE) ||
               H5Tequal(dst_id, H5T_STD_U64LE) > 0)
      {
         if (H5Tequal(src_id, H5T_STD_I8BE) > 0 ||
             H5Tequal(src_id, H5T_STD_I8LE) > 0)
            *(unsigned long long *)dst_buf = *(signed char *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U8BE) ||
                  H5Tequal(src_id, H5T_STD_U8LE) > 0)
            *(unsigned long long *)dst_buf = (unsigned char)*(float *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I16BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I16LE) > 0)
            *(unsigned long long *)dst_buf = *(signed short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U16BE) ||
                  H5Tequal(src_id, H5T_STD_U16LE) > 0)
            *(unsigned long long *)dst_buf = *(unsigned short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I32BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I32LE) > 0)
            *(unsigned long long *)dst_buf = *(signed int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U32BE) ||
                  H5Tequal(src_id, H5T_STD_U32LE) > 0)
            *(unsigned long long *)dst_buf = *(unsigned int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I64BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I64LE) > 0)
            *(unsigned long long *)dst_buf = *(signed long long *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U64BE) ||
                  H5Tequal(src_id, H5T_STD_U64LE) > 0)
            *(unsigned long long *)dst_buf = *(unsigned long long *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F32BE) > 0 ||
                  H5Tequal(src_id, H5T_IEEE_F32LE) > 0)
            *(unsigned long long *)dst_buf = *(float *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F64BE) ||
                  H5Tequal(src_id, H5T_IEEE_F64LE) > 0)
            *(unsigned long long *)dst_buf = *(double *)src_buf;
         else
         {
            printf("Unknown type!\n");
            return H5T_CONV_UNHANDLED;
         }       
      }
      else if (H5Tequal(dst_id, H5T_IEEE_F32BE) > 0 ||
               H5Tequal(dst_id, H5T_IEEE_F32LE) > 0)
      {
         if (H5Tequal(src_id, H5T_STD_I8BE) > 0 ||
             H5Tequal(src_id, H5T_STD_I8LE) > 0)
            *(float *)dst_buf = *(signed char *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U8BE) ||
                  H5Tequal(src_id, H5T_STD_U8LE) > 0)
            *(float *)dst_buf = (unsigned char)*(float *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I16BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I16LE) > 0)
            *(float *)dst_buf = *(signed short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U16BE) ||
                  H5Tequal(src_id, H5T_STD_U16LE) > 0)
            *(float *)dst_buf = *(unsigned short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I32BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I32LE) > 0)
            *(float *)dst_buf = *(signed int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U32BE) ||
                  H5Tequal(src_id, H5T_STD_U32LE) > 0)
            *(float *)dst_buf = *(unsigned int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I64BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I64LE) > 0)
            *(float *)dst_buf = *(signed long long *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U64BE) ||
                  H5Tequal(src_id, H5T_STD_U64LE) > 0)
            *(float *)dst_buf = *(unsigned long long *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F32BE) > 0 ||
                  H5Tequal(src_id, H5T_IEEE_F32LE) > 0)
            *(float *)dst_buf = *(float *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F64BE) ||
                  H5Tequal(src_id, H5T_IEEE_F64LE) > 0)
            *(float *)dst_buf = *(double *)src_buf;
         else
         {
            printf("Unknown type!\n");
            return H5T_CONV_UNHANDLED;
         }       
      }
      else if (H5Tequal(dst_id, H5T_IEEE_F64BE) ||
               H5Tequal(dst_id, H5T_IEEE_F64LE) > 0)
      {
         if (H5Tequal(src_id, H5T_STD_I8BE) > 0 ||
             H5Tequal(src_id, H5T_STD_I8LE) > 0)
            *(double *)dst_buf = *(signed char *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U8BE) ||
                  H5Tequal(src_id, H5T_STD_U8LE) > 0)
            *(double *)dst_buf = (unsigned char)*(float *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I16BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I16LE) > 0)
            *(double *)dst_buf = *(signed short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U16BE) ||
                  H5Tequal(src_id, H5T_STD_U16LE) > 0)
            *(double *)dst_buf = *(unsigned short *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I32BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I32LE) > 0)
            *(double *)dst_buf = *(signed int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U32BE) ||
                  H5Tequal(src_id, H5T_STD_U32LE) > 0)
            *(double *)dst_buf = *(unsigned int *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_I64BE) > 0 ||
                  H5Tequal(src_id, H5T_STD_I64LE) > 0)
            *(double *)dst_buf = *(signed long long *)src_buf;
         else if (H5Tequal(src_id, H5T_STD_U64BE) ||
                  H5Tequal(src_id, H5T_STD_U64LE) > 0)
            *(double *)dst_buf = *(unsigned long long *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F32BE) > 0 ||
                  H5Tequal(src_id, H5T_IEEE_F32LE) > 0)
            *(double *)dst_buf = *(float *)src_buf;
         else if (H5Tequal(src_id, H5T_IEEE_F64BE) ||
                  H5Tequal(src_id, H5T_IEEE_F64LE) > 0)
            *(double *)dst_buf = *(double *)src_buf;
         else
         {
            printf("Unknown type!\n");
            return H5T_CONV_UNHANDLED;
         }
      }
      else
      {
         printf("Unknown type!\n");
         return H5T_CONV_UNHANDLED;
      }  

      (*(int *)user_data)++;
      return H5T_CONV_HANDLED;
   }

   return H5T_CONV_UNHANDLED;
}

int
main()
{
   hid_t fileid, grpid, spaceid, typeid, datasetid, schar_datasetid;
   hid_t float_datasetid;
   hid_t xfer_plistid;
   int int_data_out[DIM1_LEN] = {-666, 0, 666};
   unsigned char uchar_data_out[DIM1_LEN] = {0, 128, 255};
   unsigned char uchar_data_in[DIM1_LEN];
   signed char schar_fill_value = 127;
   int overflow_count = 0;
   float float_data_out[DIM1_LEN] = {-.1, 9999.99, 100.001}, 
float_data_in[DIM1_LEN];
/*   float float_data_out2[DIM1_LEN] = {-2147483649.0, -2147483649.0, 
2147483648.0};*/
   float float_data_out2[DIM1_LEN] = {(float)INT_MIN - 1.0, (float)INT_MIN - 
1.0, (float)INT_MAX + 129.0};
   hsize_t dims[1];
   int i;

   printf("\n*** Checking HDF5 data type conversions.\n");
   printf("*** creating test file...");

   /* Open file and create group. */
   if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, 
                           H5P_DEFAULT)) < 0) ERR;
   if ((grpid = H5Gcreate(fileid, GRP_NAME, 0)) < 0) ERR;

   /* Create a data transfer property lists, and set up an exception
    * function which will be called whenever a conversion exception
    * happens (i.e. an overflow, truncation, or loss of precision
    * during data conversion). */
   if ((xfer_plistid = H5Pcreate(H5P_DATASET_XFER)) < 0) ERR;
   if (H5Pset_type_conv_cb(xfer_plistid, except_func, &overflow_count) < 0) ERR;

   /* Write small arrays of ints, signed chars, and floats. Just to be
    * tricky, write the uchar data out to the schar dataset. This will
    * cause overflows. */
   dims[0] = DIM1_LEN;
   if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
   if ((datasetid = H5Dcreate(grpid, INT_VAR_NAME, H5T_NATIVE_INT, 
                              spaceid, H5P_DEFAULT)) < 0) ERR;
   if ((schar_datasetid = H5Dcreate(grpid, SCHAR_VAR_NAME, H5T_NATIVE_SCHAR, 
                                    spaceid, H5P_DEFAULT)) < 0) ERR;
   if ((float_datasetid = H5Dcreate(grpid, FLOAT_VAR_NAME, H5T_NATIVE_FLOAT, 
                                    spaceid, H5P_DEFAULT)) < 0) ERR;
   if (H5Dwrite(datasetid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, xfer_plistid, 
                int_data_out) < 0) ERR;
   if (H5Dwrite(schar_datasetid, H5T_NATIVE_UCHAR, H5S_ALL, H5S_ALL, 
                xfer_plistid, uchar_data_out) < 0) ERR;
   if (H5Dwrite(float_datasetid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, 
                xfer_plistid, float_data_out) < 0) ERR;

   /* This should have produced 2 overflows. */
   if (overflow_count != 2) ERR;
   overflow_count = 0;

   if (H5Dclose(datasetid) < 0 ||
       H5Dclose(schar_datasetid) < 0 ||
       H5Dclose(float_datasetid) < 0 ||
       H5Sclose(spaceid) < 0) ERR;

   SUMMARIZE_ERR;

   /* Make sure ints can be converted into floats. Read the int
    * dataset into an array of floats, and make sure the results match
    * netcdf's conversion rules (which are exactly the C typecasting
    * rules). */
   printf("*** reading int dataset as floats...");
   if ((datasetid = H5Dopen(grpid, INT_VAR_NAME)) < 0) ERR;
   if (H5Dread(datasetid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, 
               H5P_DEFAULT, float_data_in) < 0) ERR;
   if (H5Dclose(datasetid) < 0) ERR;
   for (i=0; i<DIM1_LEN; i++)
      if (float_data_in[i] != (float)int_data_out[i]) ERR;

   /* This should have produced no overflows. */
   if (overflow_count != 0) ERR;

   SUMMARIZE_ERR;

   /* Make sure floats can be converted into schars. Read the float
    * dataset into an array of uchar. */
   printf("*** reading float dataset as uchars...");
   if ((datasetid = H5Dopen(grpid, FLOAT_VAR_NAME)) < 0) ERR;
   if (H5Dread(datasetid, H5T_NATIVE_UCHAR, H5S_ALL, H5S_ALL, 
               xfer_plistid, uchar_data_in) < 0) ERR;
   if (H5Dclose(datasetid) < 0) ERR;

   /* This should have produced 2 overflows. */
   if (overflow_count != 2) ERR;
   overflow_count = 0;

   for (i=0; i<DIM1_LEN; i++)
      if (uchar_data_in[i] != (unsigned char)float_data_out[i]) ERR;

   SUMMARIZE_ERR;
   overflow_count = 0;

   /* Now write three out of range floats to the int. This should
    * generate three exceptions. */
   printf("*** writing out of range floats to int dataset...\n");
   for (i = 0; i < DIM1_LEN; i++)
   {
      printf("float_data_out2[%d]=%f\n", i, float_data_out2[i]);
      printf("(int)float_data_out2[%d]=%d\n", i, (int)float_data_out2[i]);
   }
   if ((datasetid = H5Dopen(grpid, INT_VAR_NAME)) < 0) ERR;
   if (H5Dwrite(datasetid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, 
               xfer_plistid, float_data_out2) < 0) ERR;
   if (H5Dclose(datasetid) < 0) ERR;

   /* This should cause three overflows. */
   printf("overflow_count=%d\n", overflow_count);
   if (overflow_count != 3) ERR;
   overflow_count = 0;

   
   SUMMARIZE_ERR;

   /* Close up shop. */
   if (H5Fclose(fileid) < 0 ||
       H5Gclose(grpid) < 0) ERR;

   /* Print out our number of errors, if any, and exit badly. */
   if (total_err)
   {
      printf("%d errors detected! Sorry!\n", total_err);
      return 2;
   }
   
   printf("*** Tests successful!\n");
   return 0;
}


tests.h:

/* This is part of the netCDF package.
   Copyright 2005 University Corporation for Atmospheric Research/Unidata
   See COPYRIGHT file for conditions of use.

   Common includes, defines, etc., for test code in the libsrc4
   directory.

   $Id: tests.h,v 1.6 2005/06/06 20:36:22 ed Exp $
*/
#ifndef _NC4_TESTS_
#define _NC4_TESTS_

#include <config.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "error.h"

int total_err = 0, err = 0;

/* This is handy for print statements. */
char *format_name[] = {"", "classic", "64-bit offset", "netCDF-4", "netCDF-4 
strict NC3"};

#define ERR do { \
fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
err++; \
fprintf(stderr, "unexpected result, %s, line: %d\n", __FILE__, __LINE__); \
} while (0)

#define SUMMARIZE_ERR do { \
   if (err) \
   { \
      printf("%d failures\n", err); \
      total_err += err; \
      err = 0; \
   } \
   else \
      printf("ok.\n"); \
} while (0)


#endif /* _NC4_TESTS_ */

-- 
Ed Hartnett  -- ed@xxxxxxxxxxxxxxxx


  • 2005 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the netcdf-hdf archives: