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 | }
|
---|