Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_SetScientific.hpp
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>
15#include <string>
16#include <ios>
17
18namespace Teuchos {
19
40template<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.
49template<typename Scalar>
50class SetScientific<Scalar, true> {
51 public:
52 typedef Scalar scalar_type;
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
103 ~SetScientific () {
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
119template<class Scalar>
120class SetScientific<Scalar, false> {
121 public:
122 typedef Scalar scalar_type;
123 SetScientific(std::ostream&) {}
124 ~SetScientific() {}
125};
126
127} // namespace Teuchos
128
129#endif // TEUCHOS_SET_SCIENTIFIC_HPP
Defines basic traits for the scalar field type.
Definition of Teuchos::as, for conversions between types.
Temporarily make an output stream use scientific notation with sufficient precision.
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
This structure defines some basic traits for a scalar field type.