Hello. As practice in programming using templates, and for interest's
sake, I wrote some code to see how floating point numbers are stored
on my system. I hoped to be able to use it like:
std::cout << internal_rep(1. 0F) << std::endl;
std::cout << internal_rep(1. 0) << std::endl;
and it would give me a hexadecimal output of the bytes making up the
storage of 1.0 in float and double format.
The code I have written to do this is as follows:
#include <iostream>
#include <iomanip>
#include <vector>
#include <memory>
template<typena me T>
class internal_rep_cl ass;
template<typena me T>
std::ostream& operator<<(std: :ostream& os,
const std::auto_ptr<i nternal_rep_cla ss<T> >& rep) {
for (unsigned i = 0; i < rep->bytes.size() ; ++i)
os << std::hex
<< static_cast<uns igned int>(rep->bytes[i]) << ' ';
return os;
}
template<typena me T>
class internal_rep_cl ass {
public:
friend std::ostream& operator<< <>(std::ostream &,
const std::auto_ptr<i nternal_rep_cla ss<T> >& rep);
internal_rep_cl ass(T t) {
for (unsigned i = 0; i < sizeof(T); ++i)
bytes.push_back (
*(reinterpret_c ast<unsigned char*>(&t)+i));
}
private:
std::vector<uns igned char> bytes;
};
template<typena me T>
std::auto_ptr<i nternal_rep_cla ss<T> > internal_rep(T t) {
return std::auto_ptr<i nternal_rep_cla ss<T> >(
new internal_rep_cl ass<T>(t));
}
int main() {
std::cout << internal_rep(1. 0) << std::endl;
return 0;
}
The code apparently does what I want, but it seems overly complicated
to me. In particular the use of std::auto_ptr seems like overkill.
The reason for writing the internal_rep function was to allow me to
write
std::cout << internal_rep(1. 0) << std::endl;
rather than the slightly more inconvenient
std::cout << internal_rep_cl ass<double>(1.0 ) << std::endl;
Initially I wanted internal_rep to return a const reference. However
my understanding is that this would not work: for even though it is
legal to bind a const reference to a temporary, this reference would
be destroyed at the completion of internal_rep, and a copy of it would
actually be returned. Is this correct? (My compiler issued a warning
over the code.)
So I wonder, is there a better way that avoids the use of
std::auto_ptr or similar?
On a slightly related note, I notice that on my system
std::numeric_li mits<double>::h as_quiet_NaN
and
std::numeric_li mits<double>::h as_signaling_Na N
are both false, and
std::numeric_li mits<double>::q uiet_NaN()
and
std::numeric_li mits<double>::s ignaling_NaN()
return 0.0. However
std::cout << (0.0 / 0.0);
outputs NaN. This seems a bit counterintuitiv e - is it unusual?
sake, I wrote some code to see how floating point numbers are stored
on my system. I hoped to be able to use it like:
std::cout << internal_rep(1. 0F) << std::endl;
std::cout << internal_rep(1. 0) << std::endl;
and it would give me a hexadecimal output of the bytes making up the
storage of 1.0 in float and double format.
The code I have written to do this is as follows:
#include <iostream>
#include <iomanip>
#include <vector>
#include <memory>
template<typena me T>
class internal_rep_cl ass;
template<typena me T>
std::ostream& operator<<(std: :ostream& os,
const std::auto_ptr<i nternal_rep_cla ss<T> >& rep) {
for (unsigned i = 0; i < rep->bytes.size() ; ++i)
os << std::hex
<< static_cast<uns igned int>(rep->bytes[i]) << ' ';
return os;
}
template<typena me T>
class internal_rep_cl ass {
public:
friend std::ostream& operator<< <>(std::ostream &,
const std::auto_ptr<i nternal_rep_cla ss<T> >& rep);
internal_rep_cl ass(T t) {
for (unsigned i = 0; i < sizeof(T); ++i)
bytes.push_back (
*(reinterpret_c ast<unsigned char*>(&t)+i));
}
private:
std::vector<uns igned char> bytes;
};
template<typena me T>
std::auto_ptr<i nternal_rep_cla ss<T> > internal_rep(T t) {
return std::auto_ptr<i nternal_rep_cla ss<T> >(
new internal_rep_cl ass<T>(t));
}
int main() {
std::cout << internal_rep(1. 0) << std::endl;
return 0;
}
The code apparently does what I want, but it seems overly complicated
to me. In particular the use of std::auto_ptr seems like overkill.
The reason for writing the internal_rep function was to allow me to
write
std::cout << internal_rep(1. 0) << std::endl;
rather than the slightly more inconvenient
std::cout << internal_rep_cl ass<double>(1.0 ) << std::endl;
Initially I wanted internal_rep to return a const reference. However
my understanding is that this would not work: for even though it is
legal to bind a const reference to a temporary, this reference would
be destroyed at the completion of internal_rep, and a copy of it would
actually be returned. Is this correct? (My compiler issued a warning
over the code.)
So I wonder, is there a better way that avoids the use of
std::auto_ptr or similar?
On a slightly related note, I notice that on my system
std::numeric_li mits<double>::h as_quiet_NaN
and
std::numeric_li mits<double>::h as_signaling_Na N
are both false, and
std::numeric_li mits<double>::q uiet_NaN()
and
std::numeric_li mits<double>::s ignaling_NaN()
return 0.0. However
std::cout << (0.0 / 0.0);
outputs NaN. This seems a bit counterintuitiv e - is it unusual?