# define IVSIZE LONGSIZE
#endif
#define IV_DIG (BIT_DIGITS(IVSIZE * 8))
-#define UV_DIG (BIT_DIGITS(UVSIZE * 8))
-
-#if (IVSIZE > PTRSIZE) || (UVSIZE > PTRSIZE)
+#define UV_DIG (BIT_DIGITS(IVSIZE * 8))
+
++ /*
++ * The macros INT2PTR and NUM2PTR are (despite their names)
++ * bi-directional: they will convert int/float to or from pointers.
++ * However the conversion to int/float are named explicitly:
++ * PTR2IV, PTR2UV, PTR2NV.
++ *
++ * For int conversions we do not need two casts if pointers are
++ * the same size as IV and UV. Otherwise we need an explicit
++ * cast (PTRV) to avoid compiler warnings.
++ */
+#if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE)
+# define PTRV UV
+# define INT2PTR(any,d) (any)(d)
+#else
# if PTRSIZE == LONGSIZE
-# define PTRV unsigned long
+# define PTRV unsigned long
# else
-# define PTRV unsigned
+# define PTRV unsigned
# endif
-# define PTR_CAST (PTRV)
-#else
-# define PTRV UV
-# define PTR_CAST
+# define INT2PTR(any,d) (any)(PTRV)(d)
#endif
+#define NUM2PTR(any,d) (any)(PTRV)(d)
+#define PTR2IV(p) INT2PTR(IV,p)
+#define PTR2UV(p) INT2PTR(UV,p)
+#define PTR2NV(p) NUM2PTR(NV,p)
#ifdef USE_LONG_DOUBLE
# if defined(HAS_LONG_DOUBLE) && (LONG_DOUBLESIZE > DOUBLESIZE)