#include "testconfig.h"
#ifdef HAVE_ILOGB
#define TEST_FUNC_F_I __MATH_PRECNAME(ilogb)
#include "testdriver.h"


#ifndef FP_ILOGB0
/* The values returned by `ilogb' for 0 and NaN respectively.  */
# ifndef __FP_LOGB0_IS_MIN
#   define __FP_LOGB0_IS_MIN 1
# endif
# if __FP_LOGB0_IS_MIN
#   define FP_ILOGB0	(-__INT_MAX__ - 1)
# else
#   define FP_ILOGB0	(-__INT_MAX__)
# endif
# ifndef __FP_LOGBNAN_IS_MIN
#   ifdef __mc68000__
#     define __FP_LOGBNAN_IS_MIN 0
#   else
#     define __FP_LOGBNAN_IS_MIN 1
#   endif
# endif
# if __FP_LOGBNAN_IS_MIN
#   define FP_ILOGBNAN	(-__INT_MAX__ - 1)
# else
#   define FP_ILOGBNAN	(__INT_MAX__)
# endif
#endif


static test_f_i_data const ilogb_data[] = {
	/* ilogb (0.0) == FP_ILOGB0 plus invalid exception	*/
	{ __LINE__, ZERO_P, FP_ILOGB0, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM|FLAG_FAIL_SOFTFLOAT|FLAG_XFAIL }, /* only implemented as softfloat and thus always fails */
	{ __LINE__, ZERO_M, FP_ILOGB0, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM|FLAG_FAIL_SOFTFLOAT|FLAG_XFAIL }, /* only implemented as softfloat and thus always fails */
	/* ilogb (qNaN) == FP_ILOGBNAN plus invalid exception  */
	{ __LINE__, QNAN_P, FP_ILOGBNAN, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM|FLAG_FAIL_HARDFLOAT }, /* not handled by inline version in math-68881.h */
	{ __LINE__, QNAN_M, FP_ILOGBNAN, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM|FLAG_FAIL_HARDFLOAT }, /* not handled by inline version in math-68881.h */
	/* ilogb (inf) == INT_MAX plus invalid exception  */
	{ __LINE__, INF_P, INT_MAX, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM|FLAG_FAIL_HARDFLOAT|FLAG_FAIL_ARANYM }, /* not handled by inline version in math-68881.h */
	/* ilogb (-inf) == INT_MAX plus invalid exception  */
	{ __LINE__, INF_M, INT_MAX, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM|FLAG_FAIL_HARDFLOAT|FLAG_FAIL_ARANYM }, /* not handled by inline version in math-68881.h */

	{ __LINE__, HEXCONSTE(1, 0x3fff, 0x80000000L, 0x00000000L), 0, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONST_E, 1, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(1024, 0x4009, 0x80000000L, 0x00000000L), 10, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(-2000, 0xc009, 0xfa000000L, 0x00000000L), 10, NO_INEXACT_EXCEPTION },

	{ __LINE__, HEXCONSTE(8.50705917302346158658e+37, 0x407d, 0x80000000L, 0x00000000L), 126, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(1.17549435082228750797e-38, 0x3f81, 0x80000000L, 0x00000000L), -126, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(1.46936793852785938496e-39, 0x3f7e, 0x80000000L, 0x00000000L), -129, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(1.83670992315982423120e-40, 0x3f7b, 0x80000000L, 0x00000000L), -132, NO_INEXACT_EXCEPTION },
#if defined(TEST_FLOAT)
	{ __LINE__, MAX_P, FLT_MAX_EXP - 1, NO_INEXACT_EXCEPTION },
	{ __LINE__, MIN_P, FLT_MIN_EXP - 1, NO_INEXACT_EXCEPTION },
	{ __LINE__, SUBNORM_P, FLT_MIN_EXP - FLT_MANT_DIG, FLAG_SUBNORM|NO_INEXACT_EXCEPTION },
#endif

#if defined(TEST_DOUBLE) && DBL_MAX_EXP >= 1024
	{ __LINE__, HEXCONSTE(8.98846567431157953865e+307, 0x43fe, 0x80000000L, 0x00000000L), 1023, NO_INEXACT_EXCEPTION },
	{ __LINE__, MAX_P, DBL_MAX_EXP - 1, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(1.11253692925360069155e-308, 0x3c00, 0x80000000L, 0x00000000L), -1023, NO_INEXACT_EXCEPTION },
	{ __LINE__, MIN_P, DBL_MIN_EXP - 1, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(3.47667790391750216108e-310, 0x3bfb, 0x80000000L, 0x00000000L), -1028, NO_INEXACT_EXCEPTION },
	{ __LINE__, SUBNORM_P, DBL_MIN_EXP - DBL_MANT_DIG, FLAG_SUBNORM|NO_INEXACT_EXCEPTION },
#endif

#if defined(TEST_LDOUBLE) && LDBL_MAX_EXP >= 16384
	{ __LINE__, HEXCONSTE(5.94865747678615882543e+4931, 0x7ffe, 0x80000000L, 0x00000000L), 16383, NO_INEXACT_EXCEPTION },
	{ __LINE__, MAX_P, LDBL_MAX_EXP - 1, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(1.68105157155604675313e-4932, 0x0000, 0x40000000L, 0x00000000L), -16383, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(8.40525785778023376566e-4933, 0x0000, 0x20000000L, 0x00000000L), -16384, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(8.20825962673850953677e-4936, 0x0000, 0x00080000L, 0x00000000L), -16394, NO_INEXACT_EXCEPTION },
	{ __LINE__, HEXCONSTE(7.64453748868639537764e-4945, 0x0000, 0x00000000L, 0x00200000L), -16424, NO_INEXACT_EXCEPTION },
	{ __LINE__, MIN_P, LDBL_MIN_EXP - 1, NO_INEXACT_EXCEPTION },
	{ __LINE__, SUBNORM_P, LDBL_MIN_EXP - LDBL_MANT_DIG, FLAG_SUBNORM|NO_INEXACT_EXCEPTION },
#endif
};

int main(int argc, char **argv)
{
	int status;
	
	status = 0;
	
	test_init(argc, argv);
	
	status |= test_table_f_i(ilogb_data, ARRAY_SIZE(ilogb_data), __FILE__);
	(void)check_fp;
		
	return status ? EXIT_FAILURE : EXIT_SUCCESS;
}

#else

int main(void)
{
	return 77;
}

#endif
