-
Notifications
You must be signed in to change notification settings - Fork 6
/
float.h
215 lines (204 loc) · 7.2 KB
/
float.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/* *********************************************************************
* This Original Work is copyright of 51 Degrees Mobile Experts Limited.
* Copyright 2023 51 Degrees Mobile Experts Limited, Davidson House,
* Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
*
* This Original Work is licensed under the European Union Public Licence
* (EUPL) v.1.2 and is subject to its terms as set out below.
*
* If a copy of the EUPL was not distributed with this file, You can obtain
* one at https://opensource.org/licenses/EUPL-1.2.
*
* The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
* amended by the European Commission) shall be deemed incompatible for
* the purposes of the Work and the provisions of the compatibility
* clause in Article 5 of the EUPL shall not apply.
*
* If using the Work as, or as part of, a network application, by
* including the attribution notice(s) required under Article 5 of the EUPL
* in the end user terms of the application under an appropriate heading,
* such notice(s) shall fulfill the requirements of that article.
* ********************************************************************* */
#ifndef FIFTYONE_DEGREES_FLOAT_H_INCLUDED
#define FIFTYONE_DEGREES_FLOAT_H_INCLUDED
/**
* @ingroup FiftyOneDegreesCommon
* @defgroup fiftyoneDegreesFloat Float
*
* IEEE Single Precision Floating Point standard implementation
* and methods to convert to native float type.
*
* ## Introduction
* IEEE Single Precision Floating Point standard is supported in
* majority of modern computers. However, it is not always guaranteed,
* so a indepdent implementation is required so that on the machines where
* this standard is not supported, the float type from the data file can
* still be read correctly.
*
* ## Endianness
* Endianess difference between machines will not be handled at the
* moment, until it is supported by 51Degrees data file.
*
* ## Limitations
* Positive sign will always be defaulted to during a conversion from native
* float type when input float is NaN (Not a Number) or Inf (Infinity).
*
* When converting from 51Degrees implementation to native float type, if it results
* in a NaN or Inf, the value from compiler macros that represent
* these number will be returned. i.e. NAN and INFINITY
*
* @{
*/
#include <stdint.h>
#include "data.h"
#include "common.h"
/**
* IEEE single precision floating point bias value
*/
#define FIFTYONE_DEGREES_FLOAT_BIAS 127
/**
* IEEE single precision floating point number of bytes
*/
#define FIFTYONE_DEGREES_FLOAT_SIZE 4
/**
* IEEE single precision floating point base value
*/
#define FIFTYONE_DEGREES_FLOAT_RADIX 2
/**
* IEEE single precision floating point number of bits for sgn
*/
#define FIFTYONE_DEGREES_FLOAT_SIGN_SIZE 1
/**
* IEEE single precision floating point number of bits for exponent
*/
#define FIFTYONE_DEGREES_FLOAT_EXP_SIZE 8
/**
* IEEE single precision floating point number of bits for mantissa
*/
#define FIFTYONE_DEGREES_FLOAT_MANT_SIZE 23
/**
* IEEE single precision floating point max positive value
*/
#define FIFTYONE_DEGREES_FLOAT_MAX 3.402823466E38f
/**
* IEEE single precision floating point min positive value
*/
#define FIFTYONE_DEGREES_FLOAT_MIN 1.175494351E-38f
/**
* IEEE single precision floating point min negative value
*/
#define FIFTYONE_DEGREES_FLOAT_MIN_NEG -3.402823466E38f
/**
* IEEE single precision floating point max exponent value where all bits
* are 1. This can only happen in NaN (Not a Number) and Inf (Infinity) cases.
*/
#define FIFTYONE_DEGREES_FLOAT_EXP_MAX 255
/**
* IEEE single precision floating point max mantissa value where all bits
* are 1.
*/
#define FIFTYONE_DEGREES_FLOAT_MANT_MAX 8388607
/**
* Struture that represents 51Degrees implementation, which encapsulate
* an array of 4 bytes. This array will be formated accordingly to
* the IEEE standard
*/
typedef struct fiftyone_degrees_float_type {
byte value[FIFTYONE_DEGREES_FLOAT_SIZE];
} fiftyoneDegreesFloatInternal;
/**
* Union that breaks down 51Degrees implementation to its components:
* sign, exponent and mantissa.
*/
typedef union {
fiftyoneDegreesFloatInternal fValue;
struct {
uint32_t mantissa : FIFTYONE_DEGREES_FLOAT_MANT_SIZE;
uint32_t exponent : FIFTYONE_DEGREES_FLOAT_EXP_SIZE;
uint32_t sign : FIFTYONE_DEGREES_FLOAT_SIGN_SIZE;
} parts;
} fiftyoneDegreesFloatU;
/**
* Function that converts from a 51Degrees float implementation to a
* native float value.
* @param f input 51Degrees float value
* @return a native float value
*/
EXTERNAL float fiftyoneDegreesFloatToNative(fiftyoneDegreesFloatInternal f);
/**
* Function that converts from a native float value to 51Degrees float
* value.
* @param f input native float value
* @return a 51Degrees float value
*/
EXTERNAL fiftyoneDegreesFloatInternal fiftyoneDegreesNativeToFloat(float f);
/**
* Function that compare if two 51Degrees float values are equal
* @param f1 first input 51Degrees float value
* @param f2 second input 51Degrees float value
* @return 0 if the two are equal and 1 if they are not.
*/
EXTERNAL int fiftyoneDegreesFloatIsEqual(fiftyoneDegreesFloatInternal f1, fiftyoneDegreesFloatInternal f2);
/**
* For some compilers such as clang and Microsoft C or computers where
* the IEEE single precision standard is supported, default the type
* to the native float type.
*/
#if defined(_MSC_VER) || (defined(FLT_RADIX) && FLT_RADIX == 2 && FLT_MANT_DIG == 24 && FLT_MAX_EXP == 128 && FLT_MIN_EXP == -125)
/**
* Define 51Degrees float implementation as native float.
*/
typedef float fiftyoneDegreesFloat;
/**
* Convert from 51Degrees float to native float
* @param f 51Degrees float
* @return native float value. In this case, it is a straight map
* to the input value itself.
*/
#define FIFTYONE_DEGREES_FLOAT_TO_NATIVE(f) f
/**
* Convert from native float to 51Degrees float
* @param f native float type
* @return a 51Degrees float value. In this case, it is a straight
* map to the input value itself.
*/
#define FIFTYONE_DEGREES_NATIVE_TO_FLOAT(f) f
/**
* Compare two 51Degrees float input values.
* @param f1 a 51Degrees float input value.
* @param f2 a 51Degrees float input value.
* @return 0 if the two values are the same and 1 otherwise.
*/
#define FIFTYONE_DEGREES_FLOAT_IS_EQUAL(f1, f2) (f1 == f2 ? 0 : 1)
#else
/**
* Define 51Degrees float implementation as the internal type
* IEEE standard is not supported in this case
*/
typedef fiftyoneDegreesFloatInternal fiftyoneDegreesFloat;
/**
* Function that converts from a 51Degrees float implementation to a
* native float value.
* @param f input 51Degrees float value
* @return a native float value
*/
#define FIFTYONE_DEGREES_FLOAT_TO_NATIVE(f) fiftyoneDegreesFloatToNative(f)
/**
* Function that converts from a native float value to 51Degrees float
* value.
* @param f input native float value
* @return a 51Degrees float value
*/
#define FIFTYONE_DEGREES_NATIVE_TO_FLOAT(f) fiftyoneDegreesNativeToFloat(f)
/**
* Function that compare if two 51Degrees float values are equal
* @param f1 first input 51Degrees float value
* @param f2 second input 51Degrees float value
* @return 0 if the two are equal and 1 if they are not.
*/
#define FIFTYONE_DEGREES_FLOAT_IS_EQUAL(f1, f2) fiftyoneDegreesFloatIsEqual(f1, f2)
#endif
/**
* @}
*/
#endif