Mercurial > octave-nkf
annotate liboctave/lo-ieee.cc @ 7961:a5d1e27ee1f4 ss-3-1-51
3.1.51 snapshot
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 22 Jul 2008 11:40:48 -0400 |
parents | 87865ed7405f |
children | 090001c04619 |
rev | line source |
---|---|
1967 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, |
4 2007 John W. Eaton | |
1967 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
1967 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
1967 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
28 #include <cfloat> | |
29 | |
30 #if defined (HAVE_FLOATINGPOINT_H) | |
31 #include <floatingpoint.h> | |
32 #endif | |
33 | |
3268 | 34 #if defined (HAVE_IEEEFP_H) |
35 #include <ieeefp.h> | |
36 #endif | |
37 | |
2598 | 38 #if defined (HAVE_NAN_H) |
39 #if defined (SCO) | |
2560 | 40 #define _IEEE 1 |
2598 | 41 #endif |
2508 | 42 #include <nan.h> |
2598 | 43 #if defined (SCO) |
2560 | 44 #undef _IEEE |
2508 | 45 #endif |
2598 | 46 #endif |
2508 | 47 |
4698 | 48 #include "lo-error.h" |
1967 | 49 #include "lo-ieee.h" |
7231 | 50 #include "lo-math.h" |
4025 | 51 #include "mach-info.h" |
1967 | 52 |
53 void | |
54 octave_ieee_init (void) | |
55 { | |
4698 | 56 // Default values. DBL_MAX is not right for NaN and NA, but do you |
57 // have a better suggestion? If you don't have IEEE floating point | |
58 // values, there are many parts of Octave that will not work | |
59 // correctly. | |
60 | |
61 octave_Inf = octave_NaN = octave_NA = DBL_MAX; | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
62 octave_Float_Inf = octave_Float_NaN = octave_Float_NA = FLT_MAX; |
4698 | 63 |
4601 | 64 oct_mach_info::float_format ff = oct_mach_info::native_float_format (); |
65 | |
4698 | 66 switch (ff) |
4601 | 67 { |
4698 | 68 case oct_mach_info::flt_fmt_ieee_big_endian: |
69 case oct_mach_info::flt_fmt_ieee_little_endian: | |
70 { | |
71 // Don't optimize away tmp_inf / tmp_inf to generate octave_NaN. | |
72 | |
73 volatile double tmp_inf; | |
1967 | 74 |
2713 | 75 #if defined (SCO) |
4698 | 76 volatile double tmp = 1.0; |
77 tmp_inf = 1.0 / (tmp - tmp); | |
4164 | 78 #elif defined (__alpha__) && defined (__osf__) |
4698 | 79 extern unsigned int DINFINITY[2]; |
80 tmp_inf = (*(X_CAST(double *, DINFINITY))); | |
1967 | 81 #else |
4698 | 82 double tmp = 1e+10; |
83 tmp_inf = tmp; | |
84 for (;;) | |
85 { | |
86 tmp_inf *= 1e+10; | |
87 if (tmp_inf == tmp) | |
88 break; | |
89 tmp = tmp_inf; | |
90 } | |
1967 | 91 #endif |
92 | |
4164 | 93 #if defined (__alpha__) && defined (__osf__) |
4698 | 94 extern unsigned int DQNAN[2]; |
95 octave_NaN = (*(X_CAST(double *, DQNAN))); | |
1967 | 96 #else |
4698 | 97 octave_NaN = tmp_inf / tmp_inf; |
1967 | 98 #endif |
99 | |
4698 | 100 octave_Inf = tmp_inf; |
101 | |
102 // This is patterned after code in R. | |
103 | |
104 if (ff == oct_mach_info::flt_fmt_ieee_big_endian) | |
105 { | |
106 lo_ieee_hw = 0; | |
107 lo_ieee_lw = 1; | |
108 } | |
109 else | |
110 { | |
111 lo_ieee_hw = 1; | |
112 lo_ieee_lw = 0; | |
113 } | |
4025 | 114 |
4698 | 115 lo_ieee_double t; |
116 t.word[lo_ieee_hw] = LO_IEEE_NA_HW; | |
117 t.word[lo_ieee_lw] = LO_IEEE_NA_LW; | |
118 | |
119 octave_NA = t.value; | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
120 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
121 volatile float float_tmp_inf; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
122 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
123 #if defined (SCO) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
124 volatile float float_tmp = 1.0; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
125 float_tmp_inf = 1.0 / (float_tmp - float_tmp); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
126 #else |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
127 float float_tmp = 1e+10; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
128 float_tmp_inf = float_tmp; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
129 for (;;) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
130 { |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
131 float_tmp_inf *= 1e+10; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
132 if (float_tmp_inf == float_tmp) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
133 break; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
134 float_tmp = float_tmp_inf; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
135 } |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
136 #endif |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
137 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
138 octave_Float_NaN = float_tmp_inf / float_tmp_inf; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7231
diff
changeset
|
139 octave_Float_Inf = float_tmp_inf; |
7814
87865ed7405f
Second set of single precision test code and fix of resulting bugs
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
140 |
87865ed7405f
Second set of single precision test code and fix of resulting bugs
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
141 lo_ieee_float tf; |
87865ed7405f
Second set of single precision test code and fix of resulting bugs
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
142 tf.word = LO_IEEE_NA_FLOAT; |
87865ed7405f
Second set of single precision test code and fix of resulting bugs
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
143 octave_Float_NA = tf.value; |
4698 | 144 } |
145 break; | |
4025 | 146 |
4698 | 147 case oct_mach_info::flt_fmt_cray: |
148 case oct_mach_info::flt_fmt_vax_d: | |
149 case oct_mach_info::flt_fmt_vax_g: | |
150 break; | |
4025 | 151 |
4698 | 152 default: |
153 // If the format is unknown, then you will probably not have a | |
154 // useful system, but we will just issue a warning and go on... | |
155 (*current_liboctave_warning_handler) | |
156 ("lo_ieee_init: unrecognized floating point format!"); | |
4601 | 157 } |
1967 | 158 } |
159 | |
160 /* | |
161 ;;; Local Variables: *** | |
162 ;;; mode: C++ *** | |
163 ;;; End: *** | |
164 */ |