Titan Core Initial Contribution
[deliverable/titan.core.git] / common / ttcn3float.hh
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 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 #ifndef signbit
14 // Probably Solaris.
15 // Thankfully, IEEE Std 1003.1, 2004 Edition says that signbit is a macro,
16 // hence it's safe to use ifdef.
17
18 #ifdef __sparc
19 // Big endian
20
21 inline int signbitfunc(double d)
22 {
23 return *((unsigned char*)&d) & 0x80;
24 }
25
26 #else
27 // Probably Intel, assume little endian
28 inline int signbitfunc(double d)
29 {
30 return ((unsigned char*)&d)[sizeof(double)-1] & 0x80;
31 }
32
33 #endif
34
35 #define signbit(d) signbitfunc(d)
36
37 #endif // def signbit
38
39 /** A class which behaves almost, but not quite, entirely unlike
40 * a floating-point value.
41 *
42 * It is used as a member of a union (in Value.hh);
43 * it MUST NOT have a constructor.
44 */
45 struct ttcn3float {
46 /// Implicit conversion
47 operator double() const { return value; }
48
49 /// Assignment from a proper double
50 const ttcn3float& operator=(double d) {
51 value = d;
52 return *this;
53 }
54
55 /// Address-of, for scanf
56 double* operator&() { return &value; }
57
58 const ttcn3float& operator+=(double d) {
59 value += d;
60 return *this;
61 }
62
63 const ttcn3float& operator-=(double d) {
64 value -= d;
65 return *this;
66 }
67
68 const ttcn3float& operator*=(double d) {
69 value *= d;
70 return *this;
71 }
72
73 const ttcn3float& operator/=(double d) {
74 value /= d;
75 return *this;
76 }
77
78 bool operator<(double d) const {
79 if (isnan(value)) {
80 return false; // TTCN-3 special: NaN is bigger than anything except NaN
81 }
82 else if (isnan(d)) {
83 return true; // TTCN-3 special: NaN is bigger than anything except NaN
84 }
85 else if (value==0.0 && d==0.0) { // does not distinguish -0.0
86 return signbit(value) && !signbit(d); // value negative, d positive
87 }
88 else { // finally, the sensible behavior
89 return value < d;
90 }
91 }
92
93 bool operator>(double d) const {
94 if (isnan(value)) {
95 return true; // TTCN-3 special: NaN is bigger than anything except NaN
96 }
97 else if (isnan(d)) {
98 return false; // TTCN-3 special: NaN is bigger than anything except NaN
99 }
100 else if (value==0.0 && d==0.0) { // does not distinguish -0.0
101 return !signbit(value) && signbit(d); // value positive, d negative
102 }
103 else { // finally, the sensible behavior
104 return value > d;
105 }
106 }
107
108 bool operator==(double d) const {
109 if (isnan(value)) {
110 return !!isnan(d); // TTCN-3 special: NaN is bigger than anything except NaN
111 }
112 else if (isnan(d)) {
113 return false;
114 }
115 else if (value==0.0 && d==0.0) { // does not distinguish -0.0
116 return signbit(value) == signbit(d);
117 }
118 else { // finally, the sensible behavior
119 return value == d;
120 }
121 }
122 public:
123 double value;
124 };
125
126 /** Replacement for a user-defined constructor that ttcn3float can't have */
127 inline ttcn3float make_ttcn3float(double f) {
128 ttcn3float retval = { f };
129 return retval;
130 }
131
132 #endif /* TTCN3FLOAT_HH_ */
This page took 0.0355 seconds and 6 git commands to generate.