Merge pull request #10 from egerpil/master
[deliverable/titan.core.git] / common / ttcn3float.hh
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #ifndef TTCN3FLOAT_HH_
9 #define TTCN3FLOAT_HH_
10
11 #include <math.h>
12
13 /* TTCN-3 float values that have absolute value smaller than this
14 are displayed in exponential notation. */
15 #define MIN_DECIMAL_FLOAT 1.0E-4
16 /* TTCN-3 float values that have absolute value larger or equal than this
17 are displayed in exponential notation. */
18 #define MAX_DECIMAL_FLOAT 1.0E+10
19
20 #ifndef signbit
21 // Probably Solaris.
22 // Thankfully, IEEE Std 1003.1, 2004 Edition says that signbit is a macro,
23 // hence it's safe to use ifdef.
24
25 #ifdef __sparc
26 // Big endian
27
28 inline int signbitfunc(double d)
29 {
30 return *((unsigned char*)&d) & 0x80;
31 }
32
33 #else
34 // Probably Intel, assume little endian
35 inline int signbitfunc(double d)
36 {
37 return ((unsigned char*)&d)[sizeof(double)-1] & 0x80;
38 }
39
40 #endif
41
42 #define signbit(d) signbitfunc(d)
43
44 #endif // def signbit
45
46 /** A class which behaves almost, but not quite, entirely unlike
47 * a floating-point value.
48 *
49 * It is used as a member of a union (in Value.hh);
50 * it MUST NOT have a constructor.
51 */
52 struct ttcn3float {
53 /// Implicit conversion
54 operator double() const { return value; }
55
56 /// Assignment from a proper double
57 const ttcn3float& operator=(double d) {
58 value = d;
59 return *this;
60 }
61
62 /// Address-of, for scanf
63 double* operator&() { return &value; }
64
65 const ttcn3float& operator+=(double d) {
66 value += d;
67 return *this;
68 }
69
70 const ttcn3float& operator-=(double d) {
71 value -= d;
72 return *this;
73 }
74
75 const ttcn3float& operator*=(double d) {
76 value *= d;
77 return *this;
78 }
79
80 const ttcn3float& operator/=(double d) {
81 value /= d;
82 return *this;
83 }
84
85 bool operator<(double d) const {
86 if (isnan(value)) {
87 return false; // TTCN-3 special: NaN is bigger than anything except NaN
88 }
89 else if (isnan(d)) {
90 return true; // TTCN-3 special: NaN is bigger than anything except NaN
91 }
92 else if (value==0.0 && d==0.0) { // does not distinguish -0.0
93 return signbit(value) && !signbit(d); // value negative, d positive
94 }
95 else { // finally, the sensible behavior
96 return value < d;
97 }
98 }
99
100 bool operator>(double d) const {
101 if (isnan(value)) {
102 return true; // TTCN-3 special: NaN is bigger than anything except NaN
103 }
104 else if (isnan(d)) {
105 return false; // TTCN-3 special: NaN is bigger than anything except NaN
106 }
107 else if (value==0.0 && d==0.0) { // does not distinguish -0.0
108 return !signbit(value) && signbit(d); // value positive, d negative
109 }
110 else { // finally, the sensible behavior
111 return value > d;
112 }
113 }
114
115 bool operator==(double d) const {
116 if (isnan(value)) {
117 return !!isnan(d); // TTCN-3 special: NaN is bigger than anything except NaN
118 }
119 else if (isnan(d)) {
120 return false;
121 }
122 else if (value==0.0 && d==0.0) { // does not distinguish -0.0
123 return signbit(value) == signbit(d);
124 }
125 else { // finally, the sensible behavior
126 return value == d;
127 }
128 }
129 public:
130 double value;
131 };
132
133 /** Replacement for a user-defined constructor that ttcn3float can't have */
134 inline ttcn3float make_ttcn3float(double f) {
135 ttcn3float retval = { f };
136 return retval;
137 }
138
139 #endif /* TTCN3FLOAT_HH_ */
This page took 0.034859 seconds and 5 git commands to generate.