g2o
Toggle main menu visibility
Loading...
Searching...
No Matches
g2o
examples
interactive_slam
g2o_interactive
fast_output.h
Go to the documentation of this file.
1
/*
2
* Copyright 2005, 2006, 2007
3
* Nick Galbreath -- nickg [at] modp [dot] com
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions are
8
* met:
9
*
10
* Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
*
13
* Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* Neither the name of the modp.com nor the names of its
18
* contributors may be used to endorse or promote products derived from
19
* this software without specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
*
33
* This is the standard "new" BSD license:
34
* http://www.opensource.org/licenses/bsd-license.php
35
*/
36
37
#ifndef G2O_FAST_OUTPUT_H
38
#define G2O_FAST_OUTPUT_H
39
40
#include <cassert>
41
#include <cstdint>
42
#include <cstdio>
43
44
#ifdef __cplusplus
45
extern
"C"
{
46
#endif
47
48
inline
void
strreverse
(
char
* begin,
char
* end) {
49
while
(end > begin) {
50
char
aux = *end;
51
*end-- = *begin;
52
*begin++ = aux;
53
}
54
}
55
56
inline
int
modp_dtoa
(
double
value,
char
* str,
int
prec) {
57
static
const
double
pow10[] = {1, 10, 100, 1000,
58
10000, 100000, 1000000, 10000000,
59
100000000, 1000000000};
60
61
/* Hacky test for NaN
62
* under -fast-math this won't work, but then you also won't
63
* have correct nan values anyways. The alternative is
64
* to link with libmath (bad) or hack IEEE double bits (bad)
65
*/
66
if
(!(value == value)) {
67
str[0] =
'n'
;
68
str[1] =
'a'
;
69
str[2] =
'n'
;
70
str[3] =
'\0'
;
71
assert(0);
72
return
3;
73
}
74
/* if input is larger than thres_max, revert to exponential */
75
const
double
thres_max = (double)(0x7FFFFFFF);
76
77
double
diff = 0.0;
78
char
* wstr = str;
79
80
if
(prec < 0) {
81
prec = 0;
82
}
else
if
(prec > 9) {
83
/* precision of >= 10 can lead to overflow errors */
84
prec = 9;
85
}
86
87
/* we'll work in positive values and deal with the
88
negative sign issue later */
89
int
neg = 0;
90
if
(value < 0) {
91
neg = 1;
92
value = -value;
93
}
94
95
int
whole = (int)value;
96
double
tmp = (value - whole) * pow10[prec];
97
uint32_t frac = (uint32_t)(tmp);
98
diff = tmp - frac;
99
100
if
(diff > 0.5) {
101
++frac;
102
/* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */
103
if
(frac >= pow10[prec]) {
104
frac = 0;
105
++whole;
106
}
107
}
else
if
(diff == 0.5 && ((frac == 0) || (frac & 1))) {
108
/* if halfway, round up if odd, OR
109
if last digit is 0. That last part is strange */
110
++frac;
111
}
112
113
/* for very large numbers switch back to native sprintf for exponentials.
114
anyone want to write code to replace this? */
115
/*
116
normal printf behavior is to print EVERY whole number digit
117
which can be 100s of characters overflowing your buffers == bad
118
*/
119
if
(value > thres_max) {
120
return
sprintf(str,
"%e"
, neg ? -value : value);
121
}
122
123
if
(prec == 0) {
124
diff = value - whole;
125
if
(diff > 0.5) {
126
/* greater than 0.5, round up, e.g. 1.6 -> 2 */
127
++whole;
128
}
else
if
(diff == 0.5 && (whole & 1)) {
129
/* exactly 0.5 and ODD, then round up */
130
/* 1.5 -> 2, but 2.5 -> 2 */
131
++whole;
132
}
133
}
else
{
134
int
count = prec;
135
// now do fractional part, as an unsigned number
136
do
{
137
--count;
138
*wstr++ = (char)(48 + (frac % 10));
139
}
while
(frac /= 10);
140
// add extra 0s
141
while
(count-- > 0) *wstr++ =
'0'
;
142
// add decimal
143
*wstr++ =
'.'
;
144
}
145
146
// do whole part
147
// Take care of sign
148
// Conversion. Number is reversed.
149
do
*wstr++ = (char)(48 + (whole % 10));
150
while
(whole /= 10);
151
if
(neg) {
152
*wstr++ =
'-'
;
153
}
154
//*wstr='\0';
155
strreverse
(str, wstr - 1);
156
return
wstr - str;
157
}
158
159
inline
int
modp_uitoa10
(uint32_t value,
char
* str) {
160
char
* wstr = str;
161
// Conversion. Number is reversed.
162
do
*wstr++ = (char)(48 + (value % 10));
163
while
(value /= 10);
164
//*wstr='\0';
165
// Reverse string
166
strreverse
(str, wstr - 1);
167
return
wstr - str;
168
}
169
170
inline
int
modp_itoa10
(int32_t value,
char
* str) {
171
char
* wstr = str;
172
// Take care of sign
173
unsigned
int
uvalue = (value < 0) ? -value : value;
174
// Conversion. Number is reversed.
175
do
*wstr++ = (char)(48 + (uvalue % 10));
176
while
(uvalue /= 10);
177
if
(value < 0) *wstr++ =
'-'
;
178
*wstr =
'\0'
;
179
180
// Reverse string
181
strreverse
(str, wstr - 1);
182
return
wstr - str;
183
}
184
185
#ifdef __cplusplus
186
}
187
#endif
188
189
#endif
strreverse
void strreverse(char *begin, char *end)
Definition
fast_output.h:48
modp_itoa10
int modp_itoa10(int32_t value, char *str)
Definition
fast_output.h:170
modp_uitoa10
int modp_uitoa10(uint32_t value, char *str)
Definition
fast_output.h:159
modp_dtoa
int modp_dtoa(double value, char *str, int prec)
Definition
fast_output.h:56
Generated on
for g2o by
1.17.0