gooderp18绿色标准版
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

396 行
9.4KB

  1. /*-------------------------------------------------------------------------
  2. *
  3. * float.h
  4. * Definitions for the built-in floating-point types
  5. *
  6. * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
  7. * Portions Copyright (c) 1994, Regents of the University of California
  8. *
  9. *
  10. * IDENTIFICATION
  11. * src/include/utils/float.h
  12. *
  13. *-------------------------------------------------------------------------
  14. */
  15. #ifndef FLOAT_H
  16. #define FLOAT_H
  17. #include <math.h>
  18. #ifndef M_PI
  19. /* From my RH5.2 gcc math.h file - thomas 2000-04-03 */
  20. #define M_PI 3.14159265358979323846
  21. #endif
  22. /* Radians per degree, a.k.a. PI / 180 */
  23. #define RADIANS_PER_DEGREE 0.0174532925199432957692
  24. /* Visual C++ etc lacks NAN, and won't accept 0.0/0.0. */
  25. #if defined(WIN32) && !defined(NAN)
  26. static const uint32 nan[2] = {0xffffffff, 0x7fffffff};
  27. #define NAN (*(const float8 *) nan)
  28. #endif
  29. extern PGDLLIMPORT int extra_float_digits;
  30. /*
  31. * Utility functions in float.c
  32. */
  33. extern void float_overflow_error(void) pg_attribute_noreturn();
  34. extern void float_underflow_error(void) pg_attribute_noreturn();
  35. extern void float_zero_divide_error(void) pg_attribute_noreturn();
  36. extern int is_infinite(float8 val);
  37. extern float8 float8in_internal(char *num, char **endptr_p,
  38. const char *type_name, const char *orig_string);
  39. extern float8 float8in_internal_opt_error(char *num, char **endptr_p,
  40. const char *type_name, const char *orig_string,
  41. bool *have_error);
  42. extern char *float8out_internal(float8 num);
  43. extern int float4_cmp_internal(float4 a, float4 b);
  44. extern int float8_cmp_internal(float8 a, float8 b);
  45. /*
  46. * Routines to provide reasonably platform-independent handling of
  47. * infinity and NaN
  48. *
  49. * We assume that isinf() and isnan() are available and work per spec.
  50. * (On some platforms, we have to supply our own; see src/port.) However,
  51. * generating an Infinity or NaN in the first place is less well standardized;
  52. * pre-C99 systems tend not to have C99's INFINITY and NaN macros. We
  53. * centralize our workarounds for this here.
  54. */
  55. /*
  56. * The funny placements of the two #pragmas is necessary because of a
  57. * long lived bug in the Microsoft compilers.
  58. * See http://support.microsoft.com/kb/120968/en-us for details
  59. */
  60. #if (_MSC_VER >= 1800)
  61. #pragma warning(disable:4756)
  62. #endif
  63. static inline float4
  64. get_float4_infinity(void)
  65. {
  66. #ifdef INFINITY
  67. /* C99 standard way */
  68. return (float4) INFINITY;
  69. #else
  70. #if (_MSC_VER >= 1800)
  71. #pragma warning(default:4756)
  72. #endif
  73. /*
  74. * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the
  75. * largest normal float8. We assume forcing an overflow will get us a
  76. * true infinity.
  77. */
  78. return (float4) (HUGE_VAL * HUGE_VAL);
  79. #endif
  80. }
  81. static inline float8
  82. get_float8_infinity(void)
  83. {
  84. #ifdef INFINITY
  85. /* C99 standard way */
  86. return (float8) INFINITY;
  87. #else
  88. /*
  89. * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the
  90. * largest normal float8. We assume forcing an overflow will get us a
  91. * true infinity.
  92. */
  93. return (float8) (HUGE_VAL * HUGE_VAL);
  94. #endif
  95. }
  96. static inline float4
  97. get_float4_nan(void)
  98. {
  99. #ifdef NAN
  100. /* C99 standard way */
  101. return (float4) NAN;
  102. #else
  103. /* Assume we can get a NAN via zero divide */
  104. return (float4) (0.0 / 0.0);
  105. #endif
  106. }
  107. static inline float8
  108. get_float8_nan(void)
  109. {
  110. /* (float8) NAN doesn't work on some NetBSD/MIPS releases */
  111. #if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__))
  112. /* C99 standard way */
  113. return (float8) NAN;
  114. #else
  115. /* Assume we can get a NaN via zero divide */
  116. return (float8) (0.0 / 0.0);
  117. #endif
  118. }
  119. /*
  120. * Checks to see if a float4/8 val has underflowed or overflowed
  121. *
  122. * These subroutines are no longer used in the core code because of the
  123. * performance issues they cause, but they remain for now for backwards
  124. * compatibility for extensions. Note that we can't rely on
  125. * float_over/underflow_error() to exist in v12, so don't call those here.
  126. */
  127. static inline void
  128. check_float4_val(const float4 val, const bool inf_is_valid,
  129. const bool zero_is_valid)
  130. {
  131. if (unlikely(isinf(val)) && !inf_is_valid)
  132. ereport(ERROR,
  133. (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
  134. errmsg("value out of range: overflow")));
  135. if (unlikely(val == 0.0f) && !zero_is_valid)
  136. ereport(ERROR,
  137. (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
  138. errmsg("value out of range: underflow")));
  139. }
  140. static inline void
  141. check_float8_val(const float8 val, const bool inf_is_valid,
  142. const bool zero_is_valid)
  143. {
  144. if (unlikely(isinf(val)) && !inf_is_valid)
  145. ereport(ERROR,
  146. (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
  147. errmsg("value out of range: overflow")));
  148. if (unlikely(val == 0.0) && !zero_is_valid)
  149. ereport(ERROR,
  150. (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
  151. errmsg("value out of range: underflow")));
  152. }
  153. /*
  154. * Floating-point arithmetic with overflow/underflow reported as errors
  155. *
  156. * There isn't any way to check for underflow of addition/subtraction
  157. * because numbers near the underflow value have already been rounded to
  158. * the point where we can't detect that the two values were originally
  159. * different, e.g. on x86, '1e-45'::float4 == '2e-45'::float4 ==
  160. * 1.4013e-45.
  161. */
  162. static inline float4
  163. float4_pl(const float4 val1, const float4 val2)
  164. {
  165. float4 result;
  166. result = val1 + val2;
  167. if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
  168. float_overflow_error();
  169. return result;
  170. }
  171. static inline float8
  172. float8_pl(const float8 val1, const float8 val2)
  173. {
  174. float8 result;
  175. result = val1 + val2;
  176. if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
  177. float_overflow_error();
  178. return result;
  179. }
  180. static inline float4
  181. float4_mi(const float4 val1, const float4 val2)
  182. {
  183. float4 result;
  184. result = val1 - val2;
  185. if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
  186. float_overflow_error();
  187. return result;
  188. }
  189. static inline float8
  190. float8_mi(const float8 val1, const float8 val2)
  191. {
  192. float8 result;
  193. result = val1 - val2;
  194. if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
  195. float_overflow_error();
  196. return result;
  197. }
  198. static inline float4
  199. float4_mul(const float4 val1, const float4 val2)
  200. {
  201. float4 result;
  202. result = val1 * val2;
  203. if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
  204. float_overflow_error();
  205. if (unlikely(result == 0.0f) && val1 != 0.0f && val2 != 0.0f)
  206. float_underflow_error();
  207. return result;
  208. }
  209. static inline float8
  210. float8_mul(const float8 val1, const float8 val2)
  211. {
  212. float8 result;
  213. result = val1 * val2;
  214. if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
  215. float_overflow_error();
  216. if (unlikely(result == 0.0) && val1 != 0.0 && val2 != 0.0)
  217. float_underflow_error();
  218. return result;
  219. }
  220. static inline float4
  221. float4_div(const float4 val1, const float4 val2)
  222. {
  223. float4 result;
  224. if (unlikely(val2 == 0.0f))
  225. float_zero_divide_error();
  226. result = val1 / val2;
  227. if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
  228. float_overflow_error();
  229. if (unlikely(result == 0.0f) && val1 != 0.0f)
  230. float_underflow_error();
  231. return result;
  232. }
  233. static inline float8
  234. float8_div(const float8 val1, const float8 val2)
  235. {
  236. float8 result;
  237. if (unlikely(val2 == 0.0))
  238. float_zero_divide_error();
  239. result = val1 / val2;
  240. if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
  241. float_overflow_error();
  242. if (unlikely(result == 0.0) && val1 != 0.0)
  243. float_underflow_error();
  244. return result;
  245. }
  246. /*
  247. * Routines for NaN-aware comparisons
  248. *
  249. * We consider all NaNs to be equal and larger than any non-NaN. This is
  250. * somewhat arbitrary; the important thing is to have a consistent sort
  251. * order.
  252. */
  253. static inline bool
  254. float4_eq(const float4 val1, const float4 val2)
  255. {
  256. return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;
  257. }
  258. static inline bool
  259. float8_eq(const float8 val1, const float8 val2)
  260. {
  261. return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2;
  262. }
  263. static inline bool
  264. float4_ne(const float4 val1, const float4 val2)
  265. {
  266. return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;
  267. }
  268. static inline bool
  269. float8_ne(const float8 val1, const float8 val2)
  270. {
  271. return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2;
  272. }
  273. static inline bool
  274. float4_lt(const float4 val1, const float4 val2)
  275. {
  276. return !isnan(val1) && (isnan(val2) || val1 < val2);
  277. }
  278. static inline bool
  279. float8_lt(const float8 val1, const float8 val2)
  280. {
  281. return !isnan(val1) && (isnan(val2) || val1 < val2);
  282. }
  283. static inline bool
  284. float4_le(const float4 val1, const float4 val2)
  285. {
  286. return isnan(val2) || (!isnan(val1) && val1 <= val2);
  287. }
  288. static inline bool
  289. float8_le(const float8 val1, const float8 val2)
  290. {
  291. return isnan(val2) || (!isnan(val1) && val1 <= val2);
  292. }
  293. static inline bool
  294. float4_gt(const float4 val1, const float4 val2)
  295. {
  296. return !isnan(val2) && (isnan(val1) || val1 > val2);
  297. }
  298. static inline bool
  299. float8_gt(const float8 val1, const float8 val2)
  300. {
  301. return !isnan(val2) && (isnan(val1) || val1 > val2);
  302. }
  303. static inline bool
  304. float4_ge(const float4 val1, const float4 val2)
  305. {
  306. return isnan(val1) || (!isnan(val2) && val1 >= val2);
  307. }
  308. static inline bool
  309. float8_ge(const float8 val1, const float8 val2)
  310. {
  311. return isnan(val1) || (!isnan(val2) && val1 >= val2);
  312. }
  313. static inline float4
  314. float4_min(const float4 val1, const float4 val2)
  315. {
  316. return float4_lt(val1, val2) ? val1 : val2;
  317. }
  318. static inline float8
  319. float8_min(const float8 val1, const float8 val2)
  320. {
  321. return float8_lt(val1, val2) ? val1 : val2;
  322. }
  323. static inline float4
  324. float4_max(const float4 val1, const float4 val2)
  325. {
  326. return float4_gt(val1, val2) ? val1 : val2;
  327. }
  328. static inline float8
  329. float8_max(const float8 val1, const float8 val2)
  330. {
  331. return float8_gt(val1, val2) ? val1 : val2;
  332. }
  333. #endif /* FLOAT_H */
上海开阖软件有限公司 沪ICP备12045867号-1