The Perl Toolchain Summit 2025 Needs You: You can help 🙏 Learn more

/********************************************
Documentation of symbols defined by Math::MPFI
NV_IS_DOUBLE : Automatically defined by Makefile.PL iff
$Config{nvtype} is 'double'.
NV_IS_LONG_DOUBLE : Automatically defined by Makefile.PL iff
$Config{nvtype} is 'long double'.
NV_IS_FLOAT128 : Automatically defined by Makefile.PL iff
$Config{nvtype} is __float128
If NV_IS_FLOAT128 is defined we include the
quadmath.h header.
NOTE: mpfr_get/set_float128 are NOT necessarily
available when this symbol is defined.
MPFR_WANT_FLOAT128 : Defined by Makefile.PL if $have_float128 is
set to a true value. $have_float128 can be set
to a true value by either editing the Makefile.PL
appropriately or by specifying F128=1 in the
Makefile.PL's @ARGV.
The quadmath.h header is included if this symbol
is defined.
NOTE: If MPFR_WANT_FLOAT128 is defined, it is
assumed that the mpfr library was built with
__float128 support - ie was configured with the
'--enable-float128' option.
MPFR_WANT_FLOAT128 must NOT be defined if the
mpfr library has NOT been built with __float128
support.
MPFR_WANT_FLOAT128 does not imply that NV_IS_FLOAT128
has been defined - perhaps we have defined
MPFR_WANT_FLOAT128 solely because we wish to make
use of the Math::Float128-Math::MPFR interface.
MPFI_CAN_PASS_FLOAT128 : Defined only when both MPFR_WANT_FLOAT128 and
NV_IS_FLOAT128 is defined, and then only if the mpfr
library is at version 4.0.0 or later. (There was no
__float128 support in the mpfr library prior to
4.0.0.)
DANGER: The assumption is that if MPFR_WANT_FLOAT128
is defined then the mpfr library has been built
with __float128 support, which won't be the case if
the mpfr library wasn't configured with
'--enable-float128'.
I haven't yet found a way of managing this - it's
instead left up to the person building Math::MPFR to
NOT define MATH_MPFR_WANT_FLOAT128 unless mpfr WAS
configured with --enable-float128.
MATH_MPFI_NEED_LONG_LONG_INT
: Defined by Makefile.PL if
$Config{ivsize} >= 8 && $Config{ivtype} is not
'long' && $use_64_bit_int (in the Makefile.PL)
has not been set to -1. This symbol will also be
defined if $use_64_bit_int is set to 1.
The setting of this symbol is taken to imply that
the mpc/mpfr _uj/_sj functions are needed for
converting mpfr integer values to perl integers.
Conversely, if the symbol is not defined, then
the implication is that the _uj/sj functions are
not needed (because the _ui/_si functions, which
are alway available) provide the same
functionality) - and therefore those _uj/_sj
functions are then not made available.
_WIN32_BIZARRE_INFNAN : Defined (on Windows only) when the perl version
(as expressed by $]) is less than 5.022.
These earlier perl versions generally stringified
NaNs as (-)1.#IND and Infs as (-)1.#INF.
********************************************/
#if defined MATH_MPFI_NEED_LONG_LONG_INT
#ifndef _MSC_VER
#include <inttypes.h>
#endif
#endif
/*
* In mpfr-4.1.0, the _Float128 type is exposed in mpfr.h if MPFR_WANT_FLOAT128 is defined.
* We fall back to defining it to __float128 if the _Float128 type is unknown.
*/
#if defined(MPFR_WANT_FLOAT128) && defined(__GNUC__) && !defined(__FLT128_MAX__) && !defined(_BITS_FLOATN_H)
#define _Float128 __float128
#endif
#include <mpfi.h>
#include <mpfi_io.h>
#include <float.h>
#if defined(MPFR_WANT_FLOAT128) || defined(NV_IS_FLOAT128)
#include <quadmath.h>
#if defined(NV_IS_FLOAT128) && defined(MPFR_WANT_FLOAT128) && defined(MPFR_VERSION) && MPFR_VERSION >= MPFR_VERSION_NUM(4,0,0)
#define MPFI_CAN_PASS_FLOAT128
#endif
#if defined(__MINGW32__) && !defined(__MINGW64__)
typedef __float128 float128 __attribute__ ((aligned(32)));
#elif defined(__MINGW64__) || (defined(DEBUGGING) && defined(NV_IS_DOUBLE))
typedef __float128 float128 __attribute__ ((aligned(8)));
#else
typedef __float128 float128;
#endif
#endif
#if LDBL_MANT_DIG == 106
#define REQUIRED_LDBL_MANT_DIG 2098
#else
#define REQUIRED_LDBL_MANT_DIG LDBL_MANT_DIG
#endif
#ifdef OLDPERL
#define SvUOK SvIsUV
#endif
#ifndef Newx
# define Newx(v,n,t) New(0,v,n,t)
#endif
#ifndef Newxz
# define Newxz(v,n,t) Newz(0,v,n,t)
#endif
/* A perl bug in perl-5.20 onwards can break &PL_sv_yes and *
* &PL_sv_no. In the overload subs we therefore instead *
* use SvTRUE_nomg_NN where possible, which is available *
* beginning with perl-5.18.0. *
* Otherwise we continue using &PL_sv_yes as original *
* *
#if defined SvTRUE_nomg_NN
#define SWITCH_ARGS SvTRUE_nomg_NN(third)
#else
#define SWITCH_ARGS third==&PL_sv_yes
#endif
#ifndef __gmpfr_default_rounding_mode
#define __gmpfr_default_rounding_mode mpfr_get_default_rounding_mode()
#endif
#define SV_IS_IOK(x) \
SvIOK(x)
#define SV_IS_POK(x) \
SvPOK(x)
#define SV_IS_NOK(x) \
SvNOK(x)
#define NOK_POK_DUALVAR_CHECK \
if(SvNOK(b)) { \
nok_pok++; \
if(SvIV(get_sv("Math::MPFI::NOK_POK", 0))) \
warn("Scalar passed to %s is both NV and PV. Using PV (string) value"
/******************************************************************************
My (sisyphus) MS Visual Studio builds are unable to resolve some (comparison)
routines - eg mpfi_cmp, mpfi_cmp_d, mpfi_cmp_fr, ....
They can however resolve the "_default" versions - namely mpfi_cmp_default,
mpfi_cmp_d_default, mpfi_cmp_fr_default, etc.
So, until a better solution is found, I define (below) the following symbols
for both compilers (like Visual Studio) that can't find the non-"default"
forms, and those that can.
******************************************************************************/
#ifndef _MSC_VER
/* Unchanged - ie defined to be what was originally used */
#define MPFI_CMP_UI(x,y) mpfi_cmp_ui(x,y)
#define MPFI_CMP_SI(x,y) mpfi_cmp_si(x,y)
#define MPFI_CMP_FR(x,y) mpfi_cmp_fr(x,y)
#define MPFI_CMP_D(x,y) mpfi_cmp_d(x,y)
#define MPFI_CMP_Z(x,y) mpfi_cmp_z(x,y)
#define MPFI_CMP_Q(x,y) mpfi_cmp_q(x,y)
#define MPFI_CMP(x,y) mpfi_cmp(x,y)
#define MPFI_IS_STRICTLY_NEG(x) mpfi_is_strictly_neg(x)
#define MPFI_IS_STRICTLY_POS(x) mpfi_is_strictly_pos(x)
#define MPFI_IS_NEG(x) mpfi_is_neg(x)
#define MPFI_IS_POS(x) mpfi_is_pos(x)
#define MPFI_IS_NONNEG(x) mpfi_is_nonneg(x)
#define MPFI_IS_NONPOS(x) mpfi_is_nonpos(x)
#define MPFI_IS_ZERO_PORTABLE(x) mpfi_is_zero(x)
#else
/* Defined to use the "_default" rendition */
#define MPFI_CMP_UI(x,y) mpfi_cmp_ui_default(x,y)
#define MPFI_CMP_SI(x,y) mpfi_cmp_si_default(x,y)
#define MPFI_CMP_FR(x,y) mpfi_cmp_fr_default(x,y)
#define MPFI_CMP_D(x,y) mpfi_cmp_d_default(x,y)
#define MPFI_CMP_Z(x,y) mpfi_cmp_z_default(x,y)
#define MPFI_CMP_Q(x,y) mpfi_cmp_q_default(x,y)
#define MPFI_CMP(x,y) mpfi_cmp_default(x,y)
#define MPFI_IS_STRICTLY_NEG(x) mpfi_is_strictly_neg_default(x)
#define MPFI_IS_STRICTLY_POS(x) mpfi_is_strictly_pos_default(x)
#define MPFI_IS_NEG(x) mpfi_is_neg_default(x)
#define MPFI_IS_POS(x) mpfi_is_pos_default(x)
#define MPFI_IS_NONNEG(x) mpfi_is_nonneg_default(x)
#define MPFI_IS_NONPOS(x) mpfi_is_nonpos_default(x)
#define MPFI_IS_ZERO_PORTABLE(x) mpfi_is_zero_default(x)
#endif