blob: c9482c1d9b226a2c25f89476002f5a7b9f4753b3 (
plain)
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
|
#include <math.h>
#include "osm/types.h"
OSMFloatBreakdown osm_float_to_break(OSMFloat f)
{
OSMFloatBreakdown out;
out.sign = f >> 63;
out.mantissa = (f >> 52) & 0x7ff;
out.fraction = f & 0xfffffffffffff;
return out;
}
/*
* WARNING: This code assumes that the compiler
* supports IEEE 754 floating point numbers.
*
* Should probably be updated with more formats if I was
* feeling frisky.
*
* Supports half, single, and double precision IEEE 754
*/
OSMFloatBreakdown osm_native_float_to_break(double d)
{
OSMFloatBreakdown out = {0};
switch(sizeof(double))
{
case 2: {
uint16_t bits = *(uint16_t *) &d;
out.sign = bits >> 15;
} break;
case 4: {
uint32_t bits = * (uint32_t *) &d;
out.sign = bits >> 31;
} break;
case 8: {
uint64_t bits = * (uint64_t *) &d;
out = osm_float_to_break(bits);
} break;
default:
break;
}
return out;
}
OSMFloat osm_break_to_float(OSMFloatBreakdown b)
{
OSMFloat out;
if (b.sign)
out = 1;
out = out << 63;
out |= (OSMFloat)(b.mantissa & 0x7ff) << 52;
out |= b.fraction & 0xfffffffffffff;
return out;
}
/*
* WARNING: This code assumes that the compiler
* supports IEEE 754 floating point numbers.
*
* Should probably be updated with more formats if I was
* feeling frisky.
*/
double osm_break_to_native_float(OSMFloatBreakdown b)
{
double out = 0;
switch(sizeof(double))
{
case 2: {
} break;
case 4: {
} break;
case 8: {
OSMFloat f = osm_break_to_float(b);
out = * (double *) &f;
} break;
default:
break;
}
if (b.sign)
out = -out;
return out;
}
double osm_float_to_native(OSMFloat f)
{
return
osm_break_to_native_float(
osm_float_to_break(f)
);
}
OSMFloat osm_native_to_float(double d)
{
return
osm_break_to_float(
osm_native_float_to_break(d)
);
}
|