Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes16kdownloads
float.h358 linesDownload Raw Back to utils
1/*-------------------------------------------------------------------------2 *3 * float.h4 *	  Definitions for the built-in floating-point types5 *6 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group7 * Portions Copyright (c) 1994, Regents of the University of California8 *9 *10 * IDENTIFICATION11 *	  src/include/utils/float.h12 *13 *-------------------------------------------------------------------------14 */15#ifndef FLOAT_H16#define FLOAT_H17 18#include <math.h>19 20/* X/Open (XSI) requires <math.h> to provide M_PI, but core POSIX does not */21#ifndef M_PI22#define M_PI 3.1415926535897932384623#endif24 25/* Radians per degree, a.k.a. PI / 180 */26#define RADIANS_PER_DEGREE 0.017453292519943295769227 28/* Visual C++ etc lacks NAN, and won't accept 0.0/0.0. */29#if defined(WIN32) && !defined(NAN)30static const uint32 nan[2] = {0xffffffff, 0x7fffffff};31 32#define NAN (*(const float8 *) nan)33#endif34 35extern PGDLLIMPORT int extra_float_digits;36 37/*38 * Utility functions in float.c39 */40extern void float_overflow_error(void) pg_attribute_noreturn();41extern void float_underflow_error(void) pg_attribute_noreturn();42extern void float_zero_divide_error(void) pg_attribute_noreturn();43extern int	is_infinite(float8 val);44extern float8 float8in_internal(char *num, char **endptr_p,45								const char *type_name, const char *orig_string,46								struct Node *escontext);47extern float4 float4in_internal(char *num, char **endptr_p,48								const char *type_name, const char *orig_string,49								struct Node *escontext);50extern char *float8out_internal(float8 num);51extern int	float4_cmp_internal(float4 a, float4 b);52extern int	float8_cmp_internal(float8 a, float8 b);53 54/*55 * Routines to provide reasonably platform-independent handling of56 * infinity and NaN57 *58 * We assume that isinf() and isnan() are available and work per spec.59 * (On some platforms, we have to supply our own; see src/port.)  However,60 * generating an Infinity or NaN in the first place is less well standardized;61 * pre-C99 systems tend not to have C99's INFINITY and NaN macros.  We62 * centralize our workarounds for this here.63 */64 65/*66 * The funny placements of the two #pragmas is necessary because of a67 * long lived bug in the Microsoft compilers.68 * See http://support.microsoft.com/kb/120968/en-us for details69 */70#ifdef _MSC_VER71#pragma warning(disable:4756)72#endif73static inline float474get_float4_infinity(void)75{76#ifdef INFINITY77	/* C99 standard way */78	return (float4) INFINITY;79#else80#ifdef _MSC_VER81#pragma warning(default:4756)82#endif83 84	/*85	 * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the86	 * largest normal float8.  We assume forcing an overflow will get us a87	 * true infinity.88	 */89	return (float4) (HUGE_VAL * HUGE_VAL);90#endif91}92 93static inline float894get_float8_infinity(void)95{96#ifdef INFINITY97	/* C99 standard way */98	return (float8) INFINITY;99#else100 101	/*102	 * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the103	 * largest normal float8.  We assume forcing an overflow will get us a104	 * true infinity.105	 */106	return (float8) (HUGE_VAL * HUGE_VAL);107#endif108}109 110static inline float4111get_float4_nan(void)112{113#ifdef NAN114	/* C99 standard way */115	return (float4) NAN;116#else117	/* Assume we can get a NAN via zero divide */118	return (float4) (0.0 / 0.0);119#endif120}121 122static inline float8123get_float8_nan(void)124{125	/* (float8) NAN doesn't work on some NetBSD/MIPS releases */126#if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__))127	/* C99 standard way */128	return (float8) NAN;129#else130	/* Assume we can get a NaN via zero divide */131	return (float8) (0.0 / 0.0);132#endif133}134 135/*136 * Floating-point arithmetic with overflow/underflow reported as errors137 *138 * There isn't any way to check for underflow of addition/subtraction139 * because numbers near the underflow value have already been rounded to140 * the point where we can't detect that the two values were originally141 * different, e.g. on x86, '1e-45'::float4 == '2e-45'::float4 ==142 * 1.4013e-45.143 */144 145static inline float4146float4_pl(const float4 val1, const float4 val2)147{148	float4		result;149 150	result = val1 + val2;151	if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))152		float_overflow_error();153 154	return result;155}156 157static inline float8158float8_pl(const float8 val1, const float8 val2)159{160	float8		result;161 162	result = val1 + val2;163	if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))164		float_overflow_error();165 166	return result;167}168 169static inline float4170float4_mi(const float4 val1, const float4 val2)171{172	float4		result;173 174	result = val1 - val2;175	if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))176		float_overflow_error();177 178	return result;179}180 181static inline float8182float8_mi(const float8 val1, const float8 val2)183{184	float8		result;185 186	result = val1 - val2;187	if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))188		float_overflow_error();189 190	return result;191}192 193static inline float4194float4_mul(const float4 val1, const float4 val2)195{196	float4		result;197 198	result = val1 * val2;199	if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))200		float_overflow_error();201	if (unlikely(result == 0.0f) && val1 != 0.0f && val2 != 0.0f)202		float_underflow_error();203 204	return result;205}206 207static inline float8208float8_mul(const float8 val1, const float8 val2)209{210	float8		result;211 212	result = val1 * val2;213	if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))214		float_overflow_error();215	if (unlikely(result == 0.0) && val1 != 0.0 && val2 != 0.0)216		float_underflow_error();217 218	return result;219}220 221static inline float4222float4_div(const float4 val1, const float4 val2)223{224	float4		result;225 226	if (unlikely(val2 == 0.0f) && !isnan(val1))227		float_zero_divide_error();228	result = val1 / val2;229	if (unlikely(isinf(result)) && !isinf(val1))230		float_overflow_error();231	if (unlikely(result == 0.0f) && val1 != 0.0f && !isinf(val2))232		float_underflow_error();233 234	return result;235}236 237static inline float8238float8_div(const float8 val1, const float8 val2)239{240	float8		result;241 242	if (unlikely(val2 == 0.0) && !isnan(val1))243		float_zero_divide_error();244	result = val1 / val2;245	if (unlikely(isinf(result)) && !isinf(val1))246		float_overflow_error();247	if (unlikely(result == 0.0) && val1 != 0.0 && !isinf(val2))248		float_underflow_error();249 250	return result;251}252 253/*254 * Routines for NaN-aware comparisons255 *256 * We consider all NaNs to be equal and larger than any non-NaN. This is257 * somewhat arbitrary; the important thing is to have a consistent sort258 * order.259 */260 261static inline bool262float4_eq(const float4 val1, const float4 val2)263{264	return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;265}266 267static inline bool268float8_eq(const float8 val1, const float8 val2)269{270	return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;271}272 273static inline bool274float4_ne(const float4 val1, const float4 val2)275{276	return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;277}278 279static inline bool280float8_ne(const float8 val1, const float8 val2)281{282	return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;283}284 285static inline bool286float4_lt(const float4 val1, const float4 val2)287{288	return !isnan(val1) && (isnan(val2) || val1 < val2);289}290 291static inline bool292float8_lt(const float8 val1, const float8 val2)293{294	return !isnan(val1) && (isnan(val2) || val1 < val2);295}296 297static inline bool298float4_le(const float4 val1, const float4 val2)299{300	return isnan(val2) || (!isnan(val1) && val1 <= val2);301}302 303static inline bool304float8_le(const float8 val1, const float8 val2)305{306	return isnan(val2) || (!isnan(val1) && val1 <= val2);307}308 309static inline bool310float4_gt(const float4 val1, const float4 val2)311{312	return !isnan(val2) && (isnan(val1) || val1 > val2);313}314 315static inline bool316float8_gt(const float8 val1, const float8 val2)317{318	return !isnan(val2) && (isnan(val1) || val1 > val2);319}320 321static inline bool322float4_ge(const float4 val1, const float4 val2)323{324	return isnan(val1) || (!isnan(val2) && val1 >= val2);325}326 327static inline bool328float8_ge(const float8 val1, const float8 val2)329{330	return isnan(val1) || (!isnan(val2) && val1 >= val2);331}332 333static inline float4334float4_min(const float4 val1, const float4 val2)335{336	return float4_lt(val1, val2) ? val1 : val2;337}338 339static inline float8340float8_min(const float8 val1, const float8 val2)341{342	return float8_lt(val1, val2) ? val1 : val2;343}344 345static inline float4346float4_max(const float4 val1, const float4 val2)347{348	return float4_gt(val1, val2) ? val1 : val2;349}350 351static inline float8352float8_max(const float8 val1, const float8 val2)353{354	return float8_gt(val1, val2) ? val1 : val2;355}356 357#endif							/* FLOAT_H */358 
codekingpro/portable-devtools · Team Ai