C i C++, nazalost, imaju sve samo ne razumne defaulte za preciznost ispisa floating-point podataka. Kako ne biste uludo gubili tocnost zbog tekstualnog ispisa (i potom unosa tih istih podataka), ovdje nudim prijedlog rjesenja u vidu korisnickog parametriziranog stream manipulatora. Pretpostavite da je donji kod sadrzan u nekoj datoteci zaglavlja, npr. [tt]numIO.hpp[/tt].
[code:1]#ifndef NUM_IO_HPP_
#define NUM_IO_HPP_
#include <limits>
#include <iomanip>
#include <iostream>
// intendirani NumT: float, double, long double
template <typename NumT>
class PrecFP {
NumT _fp;
public:
static const int prec = std::numeric_limits<NumT>::digits10 + 1;
const NumT &fp() const { return _fp; }
explicit PrecFP(const NumT &fp) : _fp(fp) {}
};
template <typename NumT>
inline PrecFP<NumT> precFP(const NumT &fp) {
return PrecFP<NumT>(fp);
}
template <typename Ch, class Tr, typename NumT>
std::basic_ostream<Ch, Tr> &operator<<(std::basic_ostream<Ch, Tr> &os, const PrecFP<NumT> &pfp) {
const std::ios_base::fmtflags oldFlags =
os.flags(std::ios_base::scientific | std::ios_base::showpos | std::ios_base::uppercase);
const std::streamsize oldPrec =
os.precision(pfp.prec);
os << pfp.fp(); // error handling?
os.precision(oldPrec);
os.flags(oldFlags);
return os;
}
#endif // NUM_IO_HPP_[/code:1]
Kako to koristiti? Npr, [tt]main.cpp[/tt]:
[code:1]#include "numIO.hpp"
int main() {
double dbl = 1.00001;
float flt = 1.00001f;
std::cout << precFP(dbl) << std::endl;
std::cout << precFP(flt) << std::endl;
return 0;
}[/code:1]
Ispis bi trebao biti:
[code:1]+1.0000100000000001E+000
+1.0000100E+000[/code:1]
Npr. za [tt]double[/tt] vrijednosti ispis ima 16 decimala, a za [tt]float[/tt] 7. Predznak ispred broja i [i]scientific[/i] prikaz jamce da ce se "normalne" floating-point vrijednosti istog tipa prikazivati u istoj sirini (broju znakova) ispisa.
Naravno, ovo rjesenje samo je jedno u nizu mogucih.
C i C++, nazalost, imaju sve samo ne razumne defaulte za preciznost ispisa floating-point podataka. Kako ne biste uludo gubili tocnost zbog tekstualnog ispisa (i potom unosa tih istih podataka), ovdje nudim prijedlog rjesenja u vidu korisnickog parametriziranog stream manipulatora. Pretpostavite da je donji kod sadrzan u nekoj datoteci zaglavlja, npr. numIO.hpp.
Kod: | #ifndef NUM_IO_HPP_
#define NUM_IO_HPP_
#include <limits>
#include <iomanip>
#include <iostream>
// intendirani NumT: float, double, long double
template <typename NumT>
class PrecFP {
NumT _fp;
public:
static const int prec = std::numeric_limits<NumT>::digits10 + 1;
const NumT &fp() const { return _fp; }
explicit PrecFP(const NumT &fp) : _fp(fp) {}
};
template <typename NumT>
inline PrecFP<NumT> precFP(const NumT &fp) {
return PrecFP<NumT>(fp);
}
template <typename Ch, class Tr, typename NumT>
std::basic_ostream<Ch, Tr> &operator<<(std::basic_ostream<Ch, Tr> &os, const PrecFP<NumT> &pfp) {
const std::ios_base::fmtflags oldFlags =
os.flags(std::ios_base::scientific | std::ios_base::showpos | std::ios_base::uppercase);
const std::streamsize oldPrec =
os.precision(pfp.prec);
os << pfp.fp(); // error handling?
os.precision(oldPrec);
os.flags(oldFlags);
return os;
}
#endif // NUM_IO_HPP_ |
Kako to koristiti? Npr, main.cpp:
Kod: | #include "numIO.hpp"
int main() {
double dbl = 1.00001;
float flt = 1.00001f;
std::cout << precFP(dbl) << std::endl;
std::cout << precFP(flt) << std::endl;
return 0;
} |
Ispis bi trebao biti:
Kod: | +1.0000100000000001E+000
+1.0000100E+000 |
Npr. za double vrijednosti ispis ima 16 decimala, a za float 7. Predznak ispred broja i scientific prikaz jamce da ce se "normalne" floating-point vrijednosti istog tipa prikazivati u istoj sirini (broju znakova) ispisa.
Naravno, ovo rjesenje samo je jedno u nizu mogucih.
|