9 #ifndef ThePEG_UnitIO_H
10 #define ThePEG_UnitIO_H
21 #if defined __APPLE__ && defined __MACH__
22 extern "C" int isnan(
double) throw();
23 extern "C"
int isinf(
double) throw();
41 template <
typename T,
typename UT>
69 template <
typename T,
typename UT>
89 template <
typename T,
typename UT>
96 template <
typename T,
typename UT>
103 template <
typename OStream,
typename T,
typename UT>
110 template <
typename IStream,
typename T,
typename UT>
119 template <
typename IStream,
typename T,
typename UT>
121 std::complex<double> d;
127 template <
typename OStream,
typename T,
typename UT>
128 OStream & operator<<(OStream & os, const OUnit<T,UT> & u) {
134 template <
typename IStream,
typename T,
typename UT>
151 template <
typename T,
typename UT>
156 OUnitErr(
const T & t,
const T & dt,
const UT & u):
x(t/u),
dx(dt/u) {}
167 template <
typename T,
typename UT>
178 template <
typename OStream,
typename T,
typename UT>
179 OStream & operator<<(OStream & os, const OUnitErr<T,UT> & u) {
180 if ( isnan(u.x) || isinf(u.x) )
return os << u.x;
181 if ( isnan(u.dx) || isinf(u.dx) )
return os << u.x <<
'(' << u.dx <<
')';
182 double dx = min(u.dx, abs(u.x));
183 if ( dx <= 0.0 )
return os << u.x;
185 osse << std::scientific << setprecision(0) << dx;
186 string sse = osse.str();
187 string::size_type ee = sse.find(
'e');
188 long m =
static_cast<long>(round(abs(u.x)/std::pow(10.0,std::atoi(sse.substr(ee + 1).c_str()))));
189 int powx = m <= 0? os.precision(): int(log10(
double(m)));
190 if ( m <= 0 || powx > os.precision() ) sse[0]=
'0';
192 oss << std::scientific << setprecision(powx) << u.x;
193 string ss = oss.str();
194 string::size_type e = ss.find(
'e');
196 int pp = std::atoi(ss.substr(e + 1).c_str());
198 out << ss.substr(0, e) <<
"(" << sse[0] <<
")" << ss.substr(e);
199 else if ( (pp - 1)%3 == 0 ) {
201 oss << std::scientific << setprecision(powx) << u.x/10.0;
202 string ss = oss.str();
203 string::size_type e = ss.find(
'e');
205 out << ss.substr(0, e) <<
"0(" << sse[0] <<
"0)" << ss.substr(e);
206 else if ( powx == 1 )
207 out << ss.substr(0, ss.find(
'.'))
208 << ss.substr(ss.find(
'.') + 1, e - ss.find(
'.') - 1)
209 <<
"(" << sse[0] <<
")" << ss.substr(e);
211 swap(ss[ss.find(
'.')], ss[ss.find(
'.') + 1]);
212 out << ss.substr(0, e) <<
"(" << sse[0] <<
")" << ss.substr(e);
217 oss << std::scientific << setprecision(powx) << u.x*10.0;
218 string ss = oss.str();
219 string::size_type e = ss.find(
'e');
221 out <<
"0." << ss.substr(0, e) <<
"(" << sse[0] <<
")" << ss.substr(e);
223 swap(ss[ss.find(
'.')], ss[ss.find(
'.') - 1]);
224 out << ss.substr(0, ss.find(
'.')) <<
"0" << ss.substr(ss.find(
'.'), e)
225 <<
"(" << sse[0] <<
")" << ss.substr(e);
228 return os << out.str();
236 template <
typename T,
typename UT>
255 template <
typename T,
typename UT>
266 template <
typename IStream,
typename T,
typename UT>
273 string::size_type open = s.find(
'(');
274 string::size_type close = s.find(
')');
278 if ( open != string::npos && close != string::npos ) {
279 se = s.substr(open + 1);
280 sp += s.substr(close + 1);
281 string::size_type dot = s.find(
'.');
282 if ( dot != string::npos && dot < open ) pe = std::pow(10.0, 1.0 - (open - dot));
285 istringstream(s) >> x;
286 istringstream(se) >> dx;
287 istringstream(sp) >> ex;
290 u.
dx = dx*ex*pe*u.
ut;