1 //
2 // FPEnvironment_DEC.cpp
3 //
4 // Library: Foundation
5 // Package: Core
6 // Module: FPEnvironment
7 //
8 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9 // and Contributors.
10 //
11 // SPDX-License-Identifier: BSL-1.0
12 //
13
14
15 //
16 // _XOPEN_SOURCE disables the ieee fp functions
17 // in <math.h>, therefore we undefine it for this file.
18 //
19 #undef _XOPEN_SOURCE
20
21
22 #include <math.h>
23 #include <fp.h>
24 #include <fp_class.h>
25 #if defined(__VMS)
26 #include <starlet.h>
27 #endif
28 #include "Poco/FPEnvironment_DEC.h"
29
30
31 namespace Poco {
32
33
FPEnvironmentImpl()34 FPEnvironmentImpl::FPEnvironmentImpl()
35 {
36 #if defined(__VMS)
37 #pragma pointer_size save
38 #pragma pointer_size 32
39 struct _ieee env;
40 sys$ieee_set_fp_control(0, 0, &env);
41 #pragma pointer_size restore
42 _env = env;
43 #else
44 _env = ieee_get_fp_control();
45 #endif
46 }
47
48
FPEnvironmentImpl(const FPEnvironmentImpl & env)49 FPEnvironmentImpl::FPEnvironmentImpl(const FPEnvironmentImpl& env)
50 {
51 _env = env._env;
52 }
53
54
~FPEnvironmentImpl()55 FPEnvironmentImpl::~FPEnvironmentImpl()
56 {
57 #if defined(__VMS)
58 #pragma pointer_size save
59 #pragma pointer_size 32
60 struct _ieee mask;
61 mask.ieee$q_flags = 0xFFFFFFFFFFFFFFFF;
62 struct _ieee env = _env;
63 sys$ieee_set_fp_control(&mask, &env, 0);
64 #pragma pointer_size restore
65 #else
66 ieee_set_fp_control(_env);
67 #endif
68 }
69
70
operator =(const FPEnvironmentImpl & env)71 FPEnvironmentImpl& FPEnvironmentImpl::operator = (const FPEnvironmentImpl& env)
72 {
73 _env = env._env;
74 return *this;
75 }
76
77
isInfiniteImpl(float value)78 bool FPEnvironmentImpl::isInfiniteImpl(float value)
79 {
80 int cls = fp_classf(value);
81 return cls == FP_POS_INF || cls == FP_NEG_INF;
82 }
83
84
isInfiniteImpl(double value)85 bool FPEnvironmentImpl::isInfiniteImpl(double value)
86 {
87 int cls = fp_class(value);
88 return cls == FP_POS_INF || cls == FP_NEG_INF;
89 }
90
91
isInfiniteImpl(long double value)92 bool FPEnvironmentImpl::isInfiniteImpl(long double value)
93 {
94 int cls = fp_classl(value);
95 return cls == FP_POS_INF || cls == FP_NEG_INF;
96 }
97
98
isNaNImpl(float value)99 bool FPEnvironmentImpl::isNaNImpl(float value)
100 {
101 return isnanf(value) != 0;
102 }
103
104
isNaNImpl(double value)105 bool FPEnvironmentImpl::isNaNImpl(double value)
106 {
107 return isnan(value) != 0;
108 }
109
110
isNaNImpl(long double value)111 bool FPEnvironmentImpl::isNaNImpl(long double value)
112 {
113 return isnanl(value) != 0;
114 }
115
116
copySignImpl(float target,float source)117 float FPEnvironmentImpl::copySignImpl(float target, float source)
118 {
119 return copysignf(target, source);
120 }
121
122
copySignImpl(double target,double source)123 double FPEnvironmentImpl::copySignImpl(double target, double source)
124 {
125 return copysign(target, source);
126 }
127
128
copySignImpl(long double target,long double source)129 long double FPEnvironmentImpl::copySignImpl(long double target, long double source)
130 {
131 return copysignl(target, source);
132 }
133
134
keepCurrentImpl()135 void FPEnvironmentImpl::keepCurrentImpl()
136 {
137 #if defined(__VMS)
138 #pragma pointer_size save
139 #pragma pointer_size 32
140 struct _ieee env;
141 sys$ieee_set_fp_control(0, 0, &env);
142 #pragma pointer_size restore
143 _env = env;
144 #else
145 ieee_set_fp_control(_env);
146 #endif
147 }
148
149
clearFlagsImpl()150 void FPEnvironmentImpl::clearFlagsImpl()
151 {
152 #if defined(__VMS)
153 #pragma pointer_size save
154 #pragma pointer_size 32
155 struct _ieee mask;
156 mask.ieee$q_flags = 0xFFFFFFFFFFFFFFFF;
157 struct _ieee clr;
158 clr.ieee$q_flags = 0;
159 sys$ieee_set_fp_control(&mask, &clr, 0);
160 #pragma pointer_size restore
161 #else
162 ieee_set_fp_control(0);
163 #endif
164 }
165
166
isFlagImpl(FlagImpl flag)167 bool FPEnvironmentImpl::isFlagImpl(FlagImpl flag)
168 {
169 #if defined(__VMS)
170 #pragma pointer_size save
171 #pragma pointer_size 32
172 struct _ieee flags;
173 sys$ieee_set_fp_control(0, 0, &flags);
174 return (flags.ieee$q_flags & flag) != 0;
175 #pragma pointer_size restore
176 #else
177 return (ieee_get_fp_control() & flag) != 0;
178 #endif
179 }
180
181
setRoundingModeImpl(RoundingModeImpl mode)182 void FPEnvironmentImpl::setRoundingModeImpl(RoundingModeImpl mode)
183 {
184 // not supported
185 }
186
187
getRoundingModeImpl()188 FPEnvironmentImpl::RoundingModeImpl FPEnvironmentImpl::getRoundingModeImpl()
189 {
190 // not supported
191 return FPEnvironmentImpl::RoundingModeImpl(0);
192 }
193
194
195 } // namespace Poco
196