Fixed range warnings for floating point Simple types
authorRyan Jendoubi <ryan.jendoubi@gmail.com>
Tue, 3 Jul 2012 15:24:59 +0000 (16:24 +0100)
committerRyan Jendoubi <ryan.jendoubi@gmail.com>
Tue, 3 Jul 2012 18:58:34 +0000 (19:58 +0100)
commit28fa7b965bd77a0e556b64583b5803fddef6b069
tree9dea7b89922d39f87b72e78dcd2b556506973466
parentb6c8c89fa6df883e371c44199cf0200ccf570c9a
Fixed range warnings for floating point Simple types

Used to get warnings like:

  c_double: numeric values must be
  2.2250738585072e-308 <= x <= 1.79769313486232e+308 (got 0)

Minima for floating point types were based on the standard C
constants FLT_MIN, DBL_MIN and LDBL_MIN.

While the _MAX counterparts of these constants actually DWIM,
the _MIN values are not the minimum possible magnitudes but
the smallest value capable of being represented being
distinguishable from 0 (why this differs from the _EPSILON
constants I don't know).

To get the actual minimum possible values (magnitudes) for
these types I adopted code from the Makefile.PL of C::Dynalib
which writes, compiles and runs a small C program, in this case
outputting the actual minima, which are then written into a new
.h file under the names CTYPES_FLT_MIN, CTYPES_DBL_MIN and
CTYPES_LDBL_MIN, which file is in turn made available by being
included in Ctypes.xs.

Calculating the minimum magnitudes:
I read somewhere that on any system with IEEE 754-1985
compliant floating point handling the minimum magnitude
will in fact be simply the negative of the maximum magnitude,
"since a sign bit stored separately (no two's complement)".

In order to cater for non-compliant architectures though,
we take a low value and subtract the relevant _EPSILON value
from it until the resultant value either doesn't change or
overflows. I took -FOO_MAX + 1 as a starting point. If
there's a more efficient way of doing this please let me
know.

NB:
  * Haven't instituted tests for these types yet in Simple.t
  * CTYPES_LDBL_MIN (and indeed LDBL_MAX) exceeds the range
    of normal Perl scalars, the NV field of which are only
    doubles, not long doubles. This *will* lead to problems;
    not sure what to do about it yet.

modified:   Ctypes.xs
modified:   Makefile.PL
modified:   lib/Ctypes/Type/Simple.pm
Ctypes.xs
Makefile.PL
lib/Ctypes/Type/Simple.pm