| 1 | #include <iostream>
|
|---|
| 2 | #include <boost/lexical_cast.hpp>
|
|---|
| 3 |
|
|---|
| 4 | const unsigned short prec_mask = 0x0300;
|
|---|
| 5 | const unsigned short prec_64 = 0x0300;
|
|---|
| 6 | const unsigned short prec_53 = 0x0200;
|
|---|
| 7 | const unsigned short prec_24 = 0x0100;
|
|---|
| 8 |
|
|---|
| 9 | void print (const char* str, const double d)
|
|---|
| 10 | {
|
|---|
| 11 | union { double dbl; void* ptr; } mix;
|
|---|
| 12 | mix.dbl = d;
|
|---|
| 13 |
|
|---|
| 14 | std::cout.precision(40);
|
|---|
| 15 | std::cout << str << "(" << mix.ptr << ") " << mix.dbl << "\n";
|
|---|
| 16 | }
|
|---|
| 17 |
|
|---|
| 18 | unsigned short get_fpu_control_word()
|
|---|
| 19 | {
|
|---|
| 20 | unsigned short cw;
|
|---|
| 21 | __asm__ ("fnstcw %0" : "=m" (*&cw));
|
|---|
| 22 |
|
|---|
| 23 | std::cout << "CW: " << std::hex << cw << std::dec << "\n";
|
|---|
| 24 | return cw;
|
|---|
| 25 | }
|
|---|
| 26 |
|
|---|
| 27 | void reset_fpu_control_word (unsigned short prec)
|
|---|
| 28 | {
|
|---|
| 29 | unsigned short cw = get_fpu_control_word();
|
|---|
| 30 | cw &= ~prec_mask;
|
|---|
| 31 | cw |= prec & prec_mask;
|
|---|
| 32 | __asm__ ("fldcw %0" : : "m" (*&cw));
|
|---|
| 33 | (void)get_fpu_control_word();
|
|---|
| 34 | }
|
|---|
| 35 |
|
|---|
| 36 | void convert_str (const char* ptr)
|
|---|
| 37 | {
|
|---|
| 38 | const double d_cast = boost::lexical_cast<double>(ptr);
|
|---|
| 39 | const double d_atof = std::atof(ptr);
|
|---|
| 40 |
|
|---|
| 41 | std::istringstream strm(ptr);
|
|---|
| 42 | double d_strm(0.0); strm >> d_strm;
|
|---|
| 43 |
|
|---|
| 44 | std::cout << std::endl;
|
|---|
| 45 | std::cout << "str: " << ptr << "\n";
|
|---|
| 46 |
|
|---|
| 47 | if (d_cast != d_atof || d_cast != d_strm) std::cout << "DIFFERENT!\n";
|
|---|
| 48 | print ("boost::lexical_cast<double>: ", d_cast);
|
|---|
| 49 | print ("std::atof: ", d_atof);
|
|---|
| 50 | print ("std::istringstream: ", d_strm);
|
|---|
| 51 |
|
|---|
| 52 | std::cout << std::endl;
|
|---|
| 53 | }
|
|---|
| 54 |
|
|---|
| 55 | int main()
|
|---|
| 56 | {
|
|---|
| 57 | reset_fpu_control_word(prec_53);
|
|---|
| 58 |
|
|---|
| 59 | convert_str("-15352.00000000000");
|
|---|
| 60 | convert_str("153520000000000000000000");
|
|---|
| 61 | convert_str("1.535200000000000e+04");
|
|---|
| 62 | convert_str("4.932812500000000e+03");
|
|---|
| 63 | convert_str("4.932812500000000e+02");
|
|---|
| 64 | convert_str("4.932812500000000e+01");
|
|---|
| 65 | convert_str("49328125.00000000");
|
|---|
| 66 | convert_str("-1.600000000000001421");
|
|---|
| 67 | convert_str("-3.200000000000000178");
|
|---|
| 68 | return 0;
|
|---|
| 69 | }
|
|---|