Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_SetScientific.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Tpetra: Templated Linear Algebra Services Package
4 //
5 // Copyright 2008 NTESS and the Tpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TEUCHOS_SET_SCIENTIFIC_HPP
11 #define TEUCHOS_SET_SCIENTIFIC_HPP
12 
13 #include <Teuchos_as.hpp>
14 #include <Teuchos_ScalarTraits.hpp>
15 #include <string>
16 #include <ios>
17 
18 namespace Teuchos {
19 
40 template<typename Scalar, const bool isFloatingPoint = ! Teuchos::ScalarTraits<Scalar>::isOrdinal>
42 
43 
44 // Partial specialization of SetScientific for floating-point types.
45 //
46 // This class currently requires that std::log10() take
47 // arguments of type Scalar. This may be relaxed in the future
48 // if Teuchos::ScalarTraits gets its own log10() method.
49 template<typename Scalar>
50 class SetScientific<Scalar, true> {
51  public:
53 
54  SetScientific(std::ostream& out, int prec = -1):
55  out_(out),
56  originalFlags_(out.flags()),
57  originalPrecision_(out.precision())
58  {
59  // Print floating-point values in scientific notation.
60  out << std::scientific;
61 
63 
64  // Set the number of (decimal) digits after the decimal
65  // point to print.
66  out.precision(static_cast<std::streamsize>(prec));
67  }
68 
69  static inline int getDefaultPrecision() {
71  typedef typename STS::magnitudeType magnitude_type;
73 
74  // We're writing decimal digits, so compute the number of
75  // digits we need to get reasonable accuracy when reading
76  // values back in.
77  //
78  // There is actually an algorithm, due to Guy Steele (yes,
79  // Java's Guy Steele) et al., for idempotent printing of
80  // finite-length floating-point values. We should actually
81  // implement that algorithm, but I don't have time for that
82  // now. Currently, I just print no more than (one decimal
83  // digit more than (the number of decimal digits justified
84  // by the precision of magnitude_type)).
85  //
86  // We need to use STM's log10() rather than (say) std::log10
87  // here, because STM::base() returns a magnitude_type, not
88  // one of C++'s standard integer types.
89  const magnitude_type numDecDigits = STM::t() * STM::log10 (STM::base());
90 
91  // Round and add one. The cast to int should not overflow
92  // unless STM::t() is _extremely_ large, so we don't need to
93  // check for that case here.
94  const magnitude_type one = STM::one();
95  const magnitude_type two = one + one;
96  // Cast from magnitude_type to int, since std::ostream's
97  // precision() method expects an int input.
98  const int prec = 1 +
99  Teuchos::as<int>(magnitude_type((two*numDecDigits + one) / two));
100  return prec;
101  }
102 
104  out_.flags (originalFlags_);
105  }
106 
107  private:
109  std::ostream& out_;
110 
112  std::ios_base::fmtflags originalFlags_;
113 
115  std::streamsize originalPrecision_;
116 };
117 
119 template<class Scalar>
120 class SetScientific<Scalar, false> {
121  public:
123  SetScientific(std::ostream&) {}
125 };
126 
127 } // namespace Teuchos
128 
129 #endif // TEUCHOS_SET_SCIENTIFIC_HPP
std::streamsize originalPrecision_
The output stream&#39;s original precision.
Temporarily make an output stream use scientific notation with sufficient precision.
This structure defines some basic traits for a scalar field type.
std::ostream & out_
The output stream to which to apply flags.
SetScientific(std::ostream &out, int prec=-1)
std::ios_base::fmtflags originalFlags_
The output stream&#39;s original flags.
Defines basic traits for the scalar field type.
Definition of Teuchos::as, for conversions between types.