1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 1996-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 7 // 8 // This file is part of Octave. 9 // 10 // Octave is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Octave; see the file COPYING. If not, see 22 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if ! defined (octave_lo_ieee_h) 27 #define octave_lo_ieee_h 1 28 29 #include <cmath> 30 31 #include "octave-config.h" 32 33 #if defined (__cplusplus) 34 extern "C" { 35 #endif 36 37 /* Octave's idea of infinity. */ 38 #define octave_Inf (lo_ieee_inf_value ()) 39 40 /* Octave's idea of a missing value. */ 41 #define octave_NA (lo_ieee_na_value ()) 42 43 /* Octave's idea of not a number. */ 44 #define octave_NaN (lo_ieee_nan_value ()) 45 46 /* Octave's idea of infinity. */ 47 #define octave_Float_Inf (lo_ieee_float_inf_value ()) 48 49 /* Octave's idea of a missing value. */ 50 #define octave_Float_NA (lo_ieee_float_na_value ()) 51 52 /* Octave's idea of not a number. */ 53 #define octave_Float_NaN (lo_ieee_float_nan_value ()) 54 55 /* FIXME: This code assumes that a double has twice the 56 number of bits as an int */ 57 58 typedef union 59 { 60 double value; 61 unsigned int word[2]; 62 } lo_ieee_double; 63 64 typedef union 65 { 66 float value; 67 unsigned int word; 68 } lo_ieee_float; 69 70 #define LO_IEEE_NA_HW_OLD 0x7ff00000 71 #define LO_IEEE_NA_LW_OLD 1954 72 #if defined (HAVE_MIPS_NAN) 73 #define LO_IEEE_NA_HW 0x7FF040F4 74 #else 75 #define LO_IEEE_NA_HW 0x7FF840F4 76 #endif 77 #define LO_IEEE_NA_LW 0x40000000 78 #define LO_IEEE_NA_FLOAT 0x7FC207A2 79 80 extern OCTAVE_API void octave_ieee_init (void); 81 __lo_ieee_isnan(double x)82inline int __lo_ieee_isnan (double x) { return std::isnan (x); } __lo_ieee_finite(double x)83inline int __lo_ieee_finite (double x) { return std::isfinite (x); } __lo_ieee_isinf(double x)84inline int __lo_ieee_isinf (double x) { return std::isinf (x); } 85 86 extern OCTAVE_API int __lo_ieee_is_NA (double); 87 extern OCTAVE_API int __lo_ieee_is_old_NA (double); 88 extern OCTAVE_API double __lo_ieee_replace_old_NA (double); 89 90 extern OCTAVE_API double lo_ieee_inf_value (void); 91 extern OCTAVE_API double lo_ieee_na_value (void); 92 extern OCTAVE_API double lo_ieee_nan_value (void); 93 __lo_ieee_signbit(double x)94inline int __lo_ieee_signbit (double x) { return std::signbit (x); } 95 __lo_ieee_float_isnan(float x)96inline int __lo_ieee_float_isnan (float x) { return std::isnan (x); } __lo_ieee_float_finite(float x)97inline int __lo_ieee_float_finite (float x) { return std::isfinite (x); } __lo_ieee_float_isinf(float x)98inline int __lo_ieee_float_isinf (float x) { return std::isinf (x); } 99 100 extern OCTAVE_API int __lo_ieee_float_is_NA (float); 101 102 extern OCTAVE_API float lo_ieee_float_inf_value (void); 103 extern OCTAVE_API float lo_ieee_float_na_value (void); 104 extern OCTAVE_API float lo_ieee_float_nan_value (void); 105 __lo_ieee_float_signbit(float x)106inline int __lo_ieee_float_signbit (float x) { return std::signbit (x); } 107 108 #if defined (__cplusplus) 109 } 110 #endif 111 112 #define lo_ieee_isnan(x) \ 113 (sizeof (x) == sizeof (float) \ 114 ? __lo_ieee_float_isnan (x) : __lo_ieee_isnan (x)) 115 116 #define lo_ieee_finite(x) \ 117 (sizeof (x) == sizeof (float) \ 118 ? __lo_ieee_float_finite (x) : __lo_ieee_finite (x)) 119 120 #define lo_ieee_isinf(x) \ 121 (sizeof (x) == sizeof (float) \ 122 ? __lo_ieee_float_isinf (x) : __lo_ieee_isinf (x)) 123 124 #define lo_ieee_is_NA(x) \ 125 (sizeof (x) == sizeof (float) \ 126 ? __lo_ieee_float_is_NA (x) : __lo_ieee_is_NA (x)) 127 128 #define lo_ieee_is_NaN_or_NA(x) \ 129 (sizeof (x) == sizeof (float) \ 130 ? __lo_ieee_float_is_NaN_or_NA (x) : __lo_ieee_is_NaN_or_NA (x)) 131 132 #define lo_ieee_signbit(x) \ 133 (sizeof (x) == sizeof (float) \ 134 ? __lo_ieee_float_signbit (x) : __lo_ieee_signbit (x)) 135 136 #if defined (__cplusplus) 137 138 namespace octave 139 { 140 template <typename T> 141 struct numeric_limits 142 { NAnumeric_limits143 static T NA (void) { return static_cast<T> (0); } NaNnumeric_limits144 static T NaN (void) { return static_cast<T> (0); } Infnumeric_limits145 static T Inf (void) { return static_cast<T> (0); } 146 }; 147 148 template <> 149 struct numeric_limits<double> 150 { 151 static double NA (void) { return octave_NA; } 152 static double NaN (void) { return octave_NaN; } 153 static double Inf (void) { return octave_Inf; } 154 }; 155 156 template <> 157 struct numeric_limits<float> 158 { 159 static float NA (void) { return octave_Float_NA; } 160 static float NaN (void) { return octave_Float_NaN; } 161 static float Inf (void) { return octave_Float_Inf; } 162 }; 163 } 164 165 #endif 166 167 #endif 168