GNU Octave  4.0.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
lo-ieee.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2015 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <cfloat>
28 #include <cmath>
29 #include <cstdlib>
30 
31 #include <limits>
32 
33 static double lo_inf;
34 static double lo_nan;
35 static double lo_na;
36 
37 static float lo_float_inf;
38 static float lo_float_nan;
39 static float lo_float_na;
40 
41 static int lo_ieee_hw;
42 static int lo_ieee_lw;
43 
44 #include "lo-error.h"
45 #include "lo-ieee.h"
46 #include "lo-math.h"
47 #include "mach-info.h"
48 
49 int
51 {
52 #if defined (HAVE_CMATH_ISNAN)
53  return std::isnan (x);
54 #else
55  // Gnulib provides.
56  return isnan (x);
57 #endif
58 }
59 
60 int
62 {
63 #if defined (HAVE_CMATH_ISFINITE)
64  return std::isfinite (x);
65 #else
66  // Gnulib provides.
67  return finite (x);
68 #endif
69 }
70 
71 int
73 {
74 #if defined (HAVE_CMATH_ISINF)
75  return std::isinf (x);
76 #else
77  // Gnulib provides.
78  return isinf (x);
79 #endif
80 }
81 
82 int
84 {
86  t.value = x;
87  return (__lo_ieee_isnan (x) && t.word[lo_ieee_hw] == LO_IEEE_NA_HW
88  && t.word[lo_ieee_lw] == LO_IEEE_NA_LW) ? 1 : 0;
89 }
90 
91 int
93 {
95  t.value = x;
96  return (__lo_ieee_isnan (x) && t.word[lo_ieee_lw] == LO_IEEE_NA_LW_OLD
97  && t.word[lo_ieee_hw] == LO_IEEE_NA_HW_OLD) ? 1 : 0;
98 }
99 
100 double
102 {
103  if (__lo_ieee_is_old_NA (x))
104  return lo_ieee_na_value ();
105  else
106  return x;
107 }
108 
109 double
111 {
112  octave_ieee_init ();
113 
114  return lo_inf;
115 }
116 
117 double
119 {
120  octave_ieee_init ();
121 
122  return lo_na;
123 }
124 
125 double
127 {
128  octave_ieee_init ();
129 
130  return lo_nan;
131 }
132 
133 int
135 {
136 #if defined (HAVE_CMATH_SIGNBIT)
137  return std::signbit (x);
138 #else
139  // Gnulib provides.
140  return signbit (x);
141 #endif
142 }
143 
144 int
146 {
147 #if defined (HAVE_CMATH_ISNAN)
148  return std::isnan (x);
149 #else
150  // Gnulib provides.
151  return isnan (x);
152 #endif
153 }
154 
155 int
157 {
158 #if defined (HAVE_CMATH_ISFINITE)
159  return std::isfinite (x) != 0 && ! __lo_ieee_float_isnan (x);
160 #else
161  // Gnulib provides.
162  return finite (x);
163 #endif
164 }
165 
166 int
168 {
169 #if defined (HAVE_CMATH_ISINF)
170  return std::isinf (x);
171 #else
172  // Gnulib provides.
173  return isinf (x);
174 #endif
175 }
176 
177 int
179 {
180  lo_ieee_float t;
181  t.value = x;
182  return (__lo_ieee_float_isnan (x) && (t.word == LO_IEEE_NA_FLOAT)) ? 1 : 0;
183 }
184 
185 float
187 {
188  octave_ieee_init ();
189 
190  return lo_float_inf;
191 }
192 
193 float
195 {
196  octave_ieee_init ();
197 
198  return lo_float_na;
199 }
200 
201 float
203 {
204  octave_ieee_init ();
205 
206  return lo_float_nan;
207 }
208 
209 int
211 {
212 #if defined (HAVE_CMATH_SIGNBIT)
213  return std::signbit (x);
214 #else
215  // Gnulib provides.
216  return signbit (x);
217 #endif
218 }
219 
220 void
222 {
223  bool initialized = false;
224 
225  if (! initialized)
226  {
228 
229  switch (ff)
230  {
233  {
234  lo_nan = std::numeric_limits<double>::quiet_NaN ();
235  lo_inf = std::numeric_limits<double>::infinity ();
236 
237  lo_float_nan = std::numeric_limits<float>::quiet_NaN ();
238  lo_float_inf = std::numeric_limits<float>::infinity ();
239 
240  // The following is patterned after code in R.
241 
243  {
244  lo_ieee_hw = 0;
245  lo_ieee_lw = 1;
246  }
247  else
248  {
249  lo_ieee_hw = 1;
250  lo_ieee_lw = 0;
251  }
252 
253  lo_ieee_double t;
256 
257  lo_na = t.value;
258 
259  lo_ieee_float tf;
260  tf.word = LO_IEEE_NA_FLOAT;
261 
262  lo_float_na = tf.value;
263  }
264  break;
265 
266  default:
267  // If the format is unknown, then you will probably not have a
268  // useful system, so we will abort here. Anyone wishing to
269  // experiment with building Octave on a system without IEEE
270  // floating point should be capable of removing this check and
271  // the configure test.
272  (*current_liboctave_error_handler)
273  ("lo_ieee_init: floating point format is not IEEE! Maybe DLAMCH is miscompiled, or you are using some strange system without IEEE floating point math?");
274  abort ();
275  }
276 
277  initialized = true;
278  }
279 }
float lo_ieee_float_na_value(void)
Definition: lo-ieee.cc:194
int __lo_ieee_isnan(double x)
Definition: lo-ieee.cc:50
int __lo_ieee_signbit(double x)
Definition: lo-ieee.cc:134
double __lo_ieee_replace_old_NA(double x)
Definition: lo-ieee.cc:101
int __lo_ieee_float_signbit(float x)
Definition: lo-ieee.cc:210
unsigned int word[2]
Definition: lo-ieee.h:54
static float lo_float_nan
Definition: lo-ieee.cc:38
static double lo_inf
Definition: lo-ieee.cc:33
int __lo_ieee_float_is_NA(float x)
Definition: lo-ieee.cc:178
static int lo_ieee_hw
Definition: lo-ieee.cc:41
double lo_ieee_inf_value(void)
Definition: lo-ieee.cc:110
double lo_ieee_nan_value(void)
Definition: lo-ieee.cc:126
static int lo_ieee_lw
Definition: lo-ieee.cc:42
double value
Definition: lo-ieee.h:53
int __lo_ieee_float_isnan(float x)
Definition: lo-ieee.cc:145
static float lo_float_na
Definition: lo-ieee.cc:39
void octave_ieee_init(void)
Definition: lo-ieee.cc:221
double lo_ieee_na_value(void)
Definition: lo-ieee.cc:118
float value
Definition: lo-ieee.h:59
static double lo_na
Definition: lo-ieee.cc:35
int __lo_ieee_float_isinf(float x)
Definition: lo-ieee.cc:167
static float lo_float_inf
Definition: lo-ieee.cc:37
float lo_ieee_float_inf_value(void)
Definition: lo-ieee.cc:186
static double lo_nan
Definition: lo-ieee.cc:34
#define LO_IEEE_NA_FLOAT
Definition: lo-ieee.h:67
#define LO_IEEE_NA_HW_OLD
Definition: lo-ieee.h:63
#define LO_IEEE_NA_HW
Definition: lo-ieee.h:65
float lo_ieee_float_nan_value(void)
Definition: lo-ieee.cc:202
#define LO_IEEE_NA_LW_OLD
Definition: lo-ieee.h:64
int __lo_ieee_is_NA(double x)
Definition: lo-ieee.cc:83
static float_format native_float_format(void)
Definition: mach-info.cc:164
unsigned int word
Definition: lo-ieee.h:60
int __lo_ieee_float_finite(float x)
Definition: lo-ieee.cc:156
int __lo_ieee_is_old_NA(double x)
Definition: lo-ieee.cc:92
int __lo_ieee_isinf(double x)
Definition: lo-ieee.cc:72
int __lo_ieee_finite(double x)
Definition: lo-ieee.cc:61
F77_RET_T const double * x
#define LO_IEEE_NA_LW
Definition: lo-ieee.h:66