#include <iostream>
#include <iomanip>
#include <limits>
// Find the maximum number for double.
// assuming:
// (1) (a + b > b) if both a and b are not inf,
// (2) not (a + b > b) => a or b is inf.
// (3) not (a > a - 1) => a is max number of T or inf
using namespace std;
template <class T> void dump(T d) {
for (int i = 0; i < sizeof(d); ++i) {
cout << int(((unsigned char*)&d)[i]) << " ";
}
cout << endl;
}
template <class T> bool is_usual_num(T n) {
return (n + n > n) || (n > n - 1);
}
template <class T> void find_max() {
T d = T(1.0);
while (1) {
T n = d * 2.0;
cout << "(!(n > d && is_usual_num(n))) " << bool(!(n > d && is_usual_num(n))) <<endl;
if (!(n > d && is_usual_num(n))) {
cout << "break" << endl;
break;
}
d = n;
}
T m = T(0);
while (d >= 1.0) {
T n = m + d;
if (!(n > m && is_usual_num(n))) {
break;
}
m = n;
d = d / 2.0;
}
std::cout << "calculated = " << +m << std::endl;
std::cout << "numeric_limits = " << +numeric_limits<T>::max() << std::endl;
dump(m);
dump(numeric_limits<T>::max());
cout << endl;
}
int main(int argc, const char * argv[]) {
cout << "char" << endl;
find_max<char>();
//cout << "double" << endl;
//find_max<double>();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPGxpbWl0cz4KCi8vIEZpbmQgdGhlIG1heGltdW0gbnVtYmVyIGZvciBkb3VibGUuCi8vIGFzc3VtaW5nOgovLyAoMSkgKGEgKyBiID4gYikgaWYgYm90aCBhIGFuZCBiIGFyZSBub3QgaW5mLAovLyAoMikgbm90IChhICsgYiA+IGIpID0+IGEgb3IgYiBpcyBpbmYuCi8vICgzKSBub3QgKGEgPiBhIC0gMSkgPT4gYSBpcyBtYXggbnVtYmVyIG9mIFQgb3IgaW5mCgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGUgPGNsYXNzIFQ+IHZvaWQgZHVtcChUIGQpIHsKICBmb3IgKGludCBpID0gMDsgaSA8IHNpemVvZihkKTsgKytpKSB7CiAgICBjb3V0IDw8IGludCgoKHVuc2lnbmVkIGNoYXIqKSZkKVtpXSkgPDwgIiAiOwogIH0KICBjb3V0IDw8IGVuZGw7Cn0KCnRlbXBsYXRlIDxjbGFzcyBUPiBib29sIGlzX3VzdWFsX251bShUIG4pIHsKICByZXR1cm4gKG4gKyBuID4gbikgfHwgKG4gPiBuIC0gMSk7Cn0KCnRlbXBsYXRlIDxjbGFzcyBUPiB2b2lkIGZpbmRfbWF4KCkgewogIFQgZCA9IFQoMS4wKTsKICB3aGlsZSAoMSkgewogICAgVCBuID0gZCAqIDIuMDsKCWNvdXQgPDwgIighKG4gPiBkICYmIGlzX3VzdWFsX251bShuKSkpICIgPDwgYm9vbCghKG4gPiBkICYmIGlzX3VzdWFsX251bShuKSkpIDw8ZW5kbDsKICAgIGlmICghKG4gPiBkICYmIGlzX3VzdWFsX251bShuKSkpIHsKICAgIAljb3V0IDw8ICJicmVhayIgPDwgZW5kbDsKICAgICAgYnJlYWs7CiAgICB9CiAgICBkID0gbjsKICB9CgogIFQgbSA9IFQoMCk7CiAgd2hpbGUgKGQgPj0gMS4wKSB7CiAgICBUIG4gPSBtICsgZDsKICAgIGlmICghKG4gPiBtICYmIGlzX3VzdWFsX251bShuKSkpIHsKICAgICAgYnJlYWs7CiAgICB9CiAgICBtID0gbjsKICAgIGQgPSBkIC8gMi4wOwogIH0KICAKICBzdGQ6OmNvdXQgPDwgImNhbGN1bGF0ZWQgPSAiIDw8ICttIDw8IHN0ZDo6ZW5kbDsKICBzdGQ6OmNvdXQgPDwgIm51bWVyaWNfbGltaXRzID0gIiA8PCArbnVtZXJpY19saW1pdHM8VD46Om1heCgpIDw8IHN0ZDo6ZW5kbDsKICAKICBkdW1wKG0pOwogIGR1bXAobnVtZXJpY19saW1pdHM8VD46Om1heCgpKTsKICBjb3V0IDw8IGVuZGw7Cn0KCmludCBtYWluKGludCBhcmdjLCBjb25zdCBjaGFyICogYXJndltdKSB7CiAgCiAgY291dCA8PCAiY2hhciIgPDwgZW5kbDsKICBmaW5kX21heDxjaGFyPigpOwoKICAvL2NvdXQgPDwgImRvdWJsZSIgPDwgZW5kbDsKICAvL2ZpbmRfbWF4PGRvdWJsZT4oKTsKCiAgcmV0dXJuIDA7Cn0K