tioga 1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Tioga_README +372 -0
- data/lgpl.txt +504 -0
- data/split/Dtable/defs.h +33 -0
- data/split/Dtable/dtable.c +1928 -0
- data/split/Dtable/dtable_intern.h +144 -0
- data/split/Dtable/dvector.h +61 -0
- data/split/Dtable/extconf.rb +4 -0
- data/split/Dtable/include/dtable.h +35 -0
- data/split/Dtable/lib/Dtable_extras.rb +90 -0
- data/split/Dtable/namespace.h +47 -0
- data/split/Dtable/safe_double.h +104 -0
- data/split/Dtable/symbols.c +92 -0
- data/split/Dtable/symbols.h +52 -0
- data/split/Dvector/defs.h +33 -0
- data/split/Dvector/dvector.c +5486 -0
- data/split/Dvector/dvector_intern.h +142 -0
- data/split/Dvector/extconf.rb +4 -0
- data/split/Dvector/include/dvector.h +61 -0
- data/split/Dvector/lib/Dvector_extras.rb +328 -0
- data/split/Dvector/lib/Numeric_extras.rb +134 -0
- data/split/Dvector/namespace.h +47 -0
- data/split/Dvector/safe_double.h +104 -0
- data/split/Dvector/symbols.c +92 -0
- data/split/Dvector/symbols.h +52 -0
- data/split/Flate/defs.h +33 -0
- data/split/Flate/extconf.rb +19 -0
- data/split/Flate/flate.c +156 -0
- data/split/Flate/flate_intern.h +97 -0
- data/split/Flate/include/flate.h +98 -0
- data/split/Flate/namespace.h +47 -0
- data/split/Flate/safe_double.h +104 -0
- data/split/Flate/symbols.c +92 -0
- data/split/Flate/symbols.h +52 -0
- data/split/Function/defs.h +33 -0
- data/split/Function/dvector.h +61 -0
- data/split/Function/extconf.rb +4 -0
- data/split/Function/function.c +988 -0
- data/split/Function/joint_qsort.c +258 -0
- data/split/Function/lib/Function_extras.rb +44 -0
- data/split/Function/namespace.h +47 -0
- data/split/Function/safe_double.h +104 -0
- data/split/Function/symbols.c +92 -0
- data/split/Function/symbols.h +52 -0
- data/split/Tioga/axes.c +774 -0
- data/split/Tioga/defs.h +33 -0
- data/split/Tioga/dtable.h +35 -0
- data/split/Tioga/dvector.h +61 -0
- data/split/Tioga/extconf.rb +4 -0
- data/split/Tioga/figures.c +672 -0
- data/split/Tioga/figures.h +855 -0
- data/split/Tioga/flate.h +98 -0
- data/split/Tioga/init.c +524 -0
- data/split/Tioga/lib/Arcs_and_Circles.rb +64 -0
- data/split/Tioga/lib/ColorConstants.rb +274 -0
- data/split/Tioga/lib/Colorbars.rb +10 -0
- data/split/Tioga/lib/Colormaps.rb +105 -0
- data/split/Tioga/lib/Coordinate_Conversions.rb +194 -0
- data/split/Tioga/lib/Creating_Paths.rb +94 -0
- data/split/Tioga/lib/Doc.rb +91 -0
- data/split/Tioga/lib/Executive.rb +515 -0
- data/split/Tioga/lib/FigMkr.rb +2224 -0
- data/split/Tioga/lib/FigureConstants.rb +125 -0
- data/split/Tioga/lib/Figures_and_Plots.rb +268 -0
- data/split/Tioga/lib/Images.rb +278 -0
- data/split/Tioga/lib/Legends.rb +190 -0
- data/split/Tioga/lib/MarkerConstants.rb +122 -0
- data/split/Tioga/lib/Markers.rb +129 -0
- data/split/Tioga/lib/Page_Frame_Bounds.rb +567 -0
- data/split/Tioga/lib/Rectangles.rb +94 -0
- data/split/Tioga/lib/Shading.rb +100 -0
- data/split/Tioga/lib/Special_Paths.rb +307 -0
- data/split/Tioga/lib/Strokes.rb +129 -0
- data/split/Tioga/lib/TeX_Text.rb +454 -0
- data/split/Tioga/lib/TexPreamble.rb +358 -0
- data/split/Tioga/lib/Titles_and_Labels.rb +306 -0
- data/split/Tioga/lib/Transparency.rb +89 -0
- data/split/Tioga/lib/Using_Paths.rb +164 -0
- data/split/Tioga/lib/Utils.rb +74 -0
- data/split/Tioga/lib/X_and_Y_Axes.rb +749 -0
- data/split/Tioga/lib/irb_tioga.rb +122 -0
- data/split/Tioga/lib/tioga.rb +1 -0
- data/split/Tioga/lib/tioga_ui.rb +5 -0
- data/split/Tioga/lib/tioga_ui_cmds.rb +793 -0
- data/split/Tioga/makers.c +989 -0
- data/split/Tioga/mk_tioga_sty.rb +53 -0
- data/split/Tioga/namespace.h +47 -0
- data/split/Tioga/pdf_font_dicts.c +18253 -0
- data/split/Tioga/pdfcolor.c +486 -0
- data/split/Tioga/pdfcoords.c +505 -0
- data/split/Tioga/pdffile.c +342 -0
- data/split/Tioga/pdfimage.c +536 -0
- data/split/Tioga/pdfpath.c +914 -0
- data/split/Tioga/pdfs.h +229 -0
- data/split/Tioga/pdftext.c +443 -0
- data/split/Tioga/safe_double.h +104 -0
- data/split/Tioga/symbols.c +92 -0
- data/split/Tioga/symbols.h +52 -0
- data/split/Tioga/texout.c +380 -0
- data/split/defs.h +33 -0
- data/split/extconf.rb +107 -0
- data/split/mkmf2.rb +1612 -0
- data/split/namespace.h +47 -0
- data/split/safe_double.h +104 -0
- data/split/scripts/tioga +4 -0
- data/split/symbols.c +92 -0
- data/split/symbols.h +52 -0
- data/tests/dtable_test.data +6 -0
- data/tests/dvector_read_test.data +1 -0
- data/tests/dvector_test.data +101 -0
- data/tests/tc_Dtable.rb +221 -0
- data/tests/tc_Dvector.rb +791 -0
- data/tests/tc_FMkr.rb +162 -0
- data/tests/tc_Flate.rb +45 -0
- data/tests/tc_Function.rb +111 -0
- data/tests/ts_Tioga.rb +38 -0
- metadata +163 -0
@@ -0,0 +1,258 @@
|
|
1
|
+
/* Copyright (C) 1991,1992,1996,1997,1999,2004 Free Software Foundation, Inc.
|
2
|
+
Copyright (C) 2006 Vincent Fourmond.
|
3
|
+
This file is taken from the GNU C Library.
|
4
|
+
Written by Douglas C. Schmidt (schmidt@ics.uci.edu), modified by
|
5
|
+
Vincent Fourmond to specialize for joint sort of double arrays.
|
6
|
+
|
7
|
+
The GNU C Library is free software; you can redistribute it and/or
|
8
|
+
modify it under the terms of the GNU Lesser General Public
|
9
|
+
License as published by the Free Software Foundation; either
|
10
|
+
version 2.1 of the License, or (at your option) any later version.
|
11
|
+
|
12
|
+
The GNU C Library is distributed in the hope that it will be useful,
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
Lesser General Public License for more details.
|
16
|
+
|
17
|
+
You should have received a copy of the GNU Lesser General Public
|
18
|
+
License along with the GNU C Library; if not, write to the Free
|
19
|
+
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
20
|
+
02111-1307 USA. */
|
21
|
+
|
22
|
+
/* If you consider tuning this algorithm, you should consult first:
|
23
|
+
Engineering a sort function; Jon Bentley and M. Douglas McIlroy;
|
24
|
+
Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */
|
25
|
+
|
26
|
+
#include <namespace.h>
|
27
|
+
|
28
|
+
#include <limits.h>
|
29
|
+
#include <stdlib.h>
|
30
|
+
#include <string.h>
|
31
|
+
|
32
|
+
/* SWAP has to be completely redefined to take care of swapping *both*
|
33
|
+
arrays */
|
34
|
+
|
35
|
+
inline static void swap_one(double * a, double * b)
|
36
|
+
{
|
37
|
+
double tmp;
|
38
|
+
tmp = *a;
|
39
|
+
*a = *b;
|
40
|
+
*b = tmp;
|
41
|
+
}
|
42
|
+
|
43
|
+
#define SWAP(a,b) \
|
44
|
+
do {swap_one(a,b);\
|
45
|
+
swap_one((a - x_values + y_values), (b - x_values + y_values));}\
|
46
|
+
while(0)
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
/* Discontinue quicksort algorithm when partition gets below this size.
|
52
|
+
This particular magic number was chosen to work best on a Sun 4/260. */
|
53
|
+
#define MAX_THRESH 4
|
54
|
+
|
55
|
+
/* Stack node declarations used to store unfulfilled partition obligations. */
|
56
|
+
typedef struct
|
57
|
+
{
|
58
|
+
double *lo;
|
59
|
+
double *hi;
|
60
|
+
} stack_node;
|
61
|
+
|
62
|
+
/* The next 4 #defines implement a very fast in-line stack abstraction. */
|
63
|
+
/* The stack needs log (total_elements) entries (we could even subtract
|
64
|
+
log(MAX_THRESH)). Since total_elements has type size_t, we get as
|
65
|
+
upper bound for log (total_elements):
|
66
|
+
bits per byte (CHAR_BIT) * sizeof(size_t). */
|
67
|
+
#define STACK_SIZE (CHAR_BIT * sizeof(size_t))
|
68
|
+
#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
|
69
|
+
#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
|
70
|
+
#define STACK_NOT_EMPTY (stack < top)
|
71
|
+
|
72
|
+
|
73
|
+
/* Order size using quicksort. This implementation incorporates
|
74
|
+
four optimizations discussed in Sedgewick:
|
75
|
+
|
76
|
+
1. Non-recursive, using an explicit stack of pointer that store the
|
77
|
+
next array partition to sort. To save time, this maximum amount
|
78
|
+
of space required to store an array of SIZE_MAX is allocated on the
|
79
|
+
stack. Assuming a 32-bit (64 bit) integer for size_t, this needs
|
80
|
+
only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes).
|
81
|
+
Pretty cheap, actually.
|
82
|
+
|
83
|
+
2. Chose the pivot element using a median-of-three decision tree.
|
84
|
+
This reduces the probability of selecting a bad pivot value and
|
85
|
+
eliminates certain extraneous comparisons.
|
86
|
+
|
87
|
+
3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
|
88
|
+
insertion sort to order the MAX_THRESH items within each partition.
|
89
|
+
This is a big win, since insertion sort is faster for small, mostly
|
90
|
+
sorted array segments.
|
91
|
+
|
92
|
+
4. The larger of the two sub-partitions is always pushed onto the
|
93
|
+
stack first, with the algorithm then concentrating on the
|
94
|
+
smaller partition. This *guarantees* no more than log (total_elems)
|
95
|
+
stack size is needed (actually O(1) in this case)! */
|
96
|
+
|
97
|
+
PRIVATE
|
98
|
+
void
|
99
|
+
joint_quicksort (double *const x_values, double * const y_values,
|
100
|
+
size_t total_elems)
|
101
|
+
{
|
102
|
+
double * const base_ptr = x_values;
|
103
|
+
if (total_elems == 0)
|
104
|
+
/* Avoid lossage with unsigned arithmetic below. */
|
105
|
+
return;
|
106
|
+
|
107
|
+
if (total_elems > MAX_THRESH)
|
108
|
+
{
|
109
|
+
double *lo = base_ptr;
|
110
|
+
double *hi = lo + (total_elems - 1);
|
111
|
+
stack_node stack[STACK_SIZE];
|
112
|
+
stack_node *top = stack;
|
113
|
+
|
114
|
+
PUSH (NULL, NULL);
|
115
|
+
|
116
|
+
while (STACK_NOT_EMPTY)
|
117
|
+
{
|
118
|
+
double *left_ptr;
|
119
|
+
double *right_ptr;
|
120
|
+
|
121
|
+
/* Select median value from among LO, MID, and HI. Rearrange
|
122
|
+
LO and HI so the three values are sorted. This lowers the
|
123
|
+
probability of picking a pathological pivot value and
|
124
|
+
skips a comparison for both the LEFT_PTR and RIGHT_PTR in
|
125
|
+
the while loops. */
|
126
|
+
|
127
|
+
double *mid = lo + ((hi - lo) >> 1);
|
128
|
+
|
129
|
+
if (*mid < *lo)
|
130
|
+
SWAP (mid, lo);
|
131
|
+
if (*hi < *mid)
|
132
|
+
SWAP (mid, hi);
|
133
|
+
else
|
134
|
+
goto jump_over;
|
135
|
+
if (*mid < *lo)
|
136
|
+
SWAP (mid, lo);
|
137
|
+
|
138
|
+
jump_over:;
|
139
|
+
|
140
|
+
left_ptr = lo + 1;
|
141
|
+
right_ptr = hi - 1;
|
142
|
+
|
143
|
+
/* Here's the famous ``collapse the walls'' section of quicksort.
|
144
|
+
Gotta like those tight inner loops! They are the main reason
|
145
|
+
that this algorithm runs much faster than others. */
|
146
|
+
do
|
147
|
+
{
|
148
|
+
while (*left_ptr < *mid)
|
149
|
+
left_ptr ++;
|
150
|
+
while (*mid < *right_ptr)
|
151
|
+
right_ptr --;
|
152
|
+
|
153
|
+
if (left_ptr < right_ptr)
|
154
|
+
{
|
155
|
+
SWAP (left_ptr, right_ptr);
|
156
|
+
if (mid == left_ptr)
|
157
|
+
mid = right_ptr;
|
158
|
+
else if (mid == right_ptr)
|
159
|
+
mid = left_ptr;
|
160
|
+
left_ptr ++;
|
161
|
+
right_ptr --;
|
162
|
+
}
|
163
|
+
else if (left_ptr == right_ptr)
|
164
|
+
{
|
165
|
+
left_ptr ++;
|
166
|
+
right_ptr --;
|
167
|
+
break;
|
168
|
+
}
|
169
|
+
}
|
170
|
+
while (left_ptr <= right_ptr);
|
171
|
+
|
172
|
+
/* Set up pointers for next iteration. First determine whether
|
173
|
+
left and right partitions are below the threshold size. If so,
|
174
|
+
ignore one or both. Otherwise, push the larger partition's
|
175
|
+
bounds on the stack and continue sorting the smaller one. */
|
176
|
+
|
177
|
+
if ((size_t) (right_ptr - lo) <= MAX_THRESH)
|
178
|
+
{
|
179
|
+
if ((size_t) (hi - left_ptr) <= MAX_THRESH)
|
180
|
+
/* Ignore both small partitions. */
|
181
|
+
POP (lo, hi);
|
182
|
+
else
|
183
|
+
/* Ignore small left partition. */
|
184
|
+
lo = left_ptr;
|
185
|
+
}
|
186
|
+
else if ((size_t) (hi - left_ptr) <= MAX_THRESH)
|
187
|
+
/* Ignore small right partition. */
|
188
|
+
hi = right_ptr;
|
189
|
+
else if ((right_ptr - lo) > (hi - left_ptr))
|
190
|
+
{
|
191
|
+
/* Push larger left partition indices. */
|
192
|
+
PUSH (lo, right_ptr);
|
193
|
+
lo = left_ptr;
|
194
|
+
}
|
195
|
+
else
|
196
|
+
{
|
197
|
+
/* Push larger right partition indices. */
|
198
|
+
PUSH (left_ptr, hi);
|
199
|
+
hi = right_ptr;
|
200
|
+
}
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
/* Once the BASE_PTR array is partially sorted by quicksort the rest
|
205
|
+
is completely sorted using insertion sort, since this is efficient
|
206
|
+
for partitions below MAX_THRESH size. BASE_PTR points to the beginning
|
207
|
+
of the array to sort, and END_PTR points at the very last element in
|
208
|
+
the array (*not* one beyond it!). */
|
209
|
+
|
210
|
+
#define min(x, y) ((x) < (y) ? (x) : (y))
|
211
|
+
|
212
|
+
{
|
213
|
+
double *const end_ptr = base_ptr + (total_elems - 1);
|
214
|
+
double *tmp_ptr = base_ptr;
|
215
|
+
double *thresh = min(end_ptr, base_ptr + MAX_THRESH);
|
216
|
+
double *run_ptr;
|
217
|
+
|
218
|
+
/* Find smallest element in first threshold and place it at the
|
219
|
+
array's beginning. This is the smallest array element,
|
220
|
+
and the operation speeds up insertion sort's inner loop. */
|
221
|
+
|
222
|
+
for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr ++)
|
223
|
+
if (*run_ptr < *tmp_ptr)
|
224
|
+
tmp_ptr = run_ptr;
|
225
|
+
|
226
|
+
if (tmp_ptr != base_ptr)
|
227
|
+
SWAP (tmp_ptr, base_ptr);
|
228
|
+
|
229
|
+
/* Insertion sort, running from left-hand-side up to right-hand-side. */
|
230
|
+
|
231
|
+
run_ptr = base_ptr + 1;
|
232
|
+
while ((run_ptr ++) < end_ptr)
|
233
|
+
{
|
234
|
+
tmp_ptr = run_ptr - 1;
|
235
|
+
while (*run_ptr < *tmp_ptr)
|
236
|
+
tmp_ptr --;
|
237
|
+
|
238
|
+
tmp_ptr ++;
|
239
|
+
if (tmp_ptr != run_ptr)
|
240
|
+
{
|
241
|
+
double tmp = *run_ptr;
|
242
|
+
double tmp_y = *(run_ptr - x_values + y_values);
|
243
|
+
double * trav = run_ptr;
|
244
|
+
while(--trav >= tmp_ptr)
|
245
|
+
{
|
246
|
+
*(trav + 1) = *trav;
|
247
|
+
*(trav + 1 - x_values + y_values) =
|
248
|
+
*(trav - x_values + y_values);
|
249
|
+
}
|
250
|
+
*tmp_ptr = tmp;
|
251
|
+
*(tmp_ptr - x_values + y_values) = tmp_y;
|
252
|
+
}
|
253
|
+
}
|
254
|
+
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
/* Hey, it miraculously looks like I got it right... */
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Function_extras.rb
|
2
|
+
#
|
3
|
+
# Some extra functions that are much more compact and hardly any slower in
|
4
|
+
# pure Ruby
|
5
|
+
#
|
6
|
+
# Copyright (C) 2006 Vincent Fourmond
|
7
|
+
#
|
8
|
+
# This program is free software; you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Library Public License as published
|
10
|
+
# by the Free Software Foundation; either version 2 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU Library General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Library General Public License
|
19
|
+
# along with this program; if not, write to the Free Software
|
20
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
21
|
+
|
22
|
+
|
23
|
+
module Dobjects
|
24
|
+
class Function
|
25
|
+
|
26
|
+
# Returns [xmin, ymin, xmax, ymax]
|
27
|
+
def bounds
|
28
|
+
xmin,xmax = x.bounds
|
29
|
+
ymin,ymax = y.bounds
|
30
|
+
return [xmin, ymin, xmax, ymax]
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the point where Y is the minimum
|
34
|
+
def min
|
35
|
+
return point(y.where_min)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns the point where Y is the maximum
|
39
|
+
def max
|
40
|
+
return point(y.where_max)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
/* namespace.h: an attempt at rationalizing shared objects
|
2
|
+
namespace use.
|
3
|
+
|
4
|
+
Copyright (C) 2006 Vincent Fourmond
|
5
|
+
|
6
|
+
This program is free software; you can redistribute it and/or modify
|
7
|
+
it under the terms of the GNU General Library Public License as published
|
8
|
+
by the Free Software Foundation; either version 2 of the License, or
|
9
|
+
(at your option) any later version.
|
10
|
+
|
11
|
+
This program is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU Library General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU Library General Public License
|
17
|
+
along with this program; if not, write to the Free Software
|
18
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
*/
|
20
|
+
|
21
|
+
#ifndef _NAMESPACE_H
|
22
|
+
#define _NAMESPACE_H
|
23
|
+
|
24
|
+
/* This header file provides two OS-specific macros for the definition of
|
25
|
+
extern symbols:
|
26
|
+
|
27
|
+
* PUBLIC, which has to be used to mark objects that will be used
|
28
|
+
outside the module
|
29
|
+
|
30
|
+
* PRIVATE, for symbols which are "extern" but intern to the module
|
31
|
+
|
32
|
+
Please don't add "extern" after the PRIVATE or PUBLIC declaration
|
33
|
+
as this would break compilation on Darwin.
|
34
|
+
*/
|
35
|
+
|
36
|
+
#ifdef __APPLE__
|
37
|
+
# define PRIVATE __private_extern__
|
38
|
+
# define PUBLIC
|
39
|
+
#elif __GNUC__ >= 4 /* we have the visibility attribute */
|
40
|
+
# define PRIVATE __attribute__ ((visibility ("hidden")))
|
41
|
+
# define PUBLIC __attribute__ ((visibility ("default")))
|
42
|
+
#else /* not really good */
|
43
|
+
# define PRIVATE
|
44
|
+
# define PUBLIC
|
45
|
+
#endif /* __APPLE__ and __GNU_C_ >= 4*/
|
46
|
+
|
47
|
+
#endif
|
@@ -0,0 +1,104 @@
|
|
1
|
+
/**********************************************************************
|
2
|
+
|
3
|
+
safe_double.h: small abstraction for storing double without endianess
|
4
|
+
problems
|
5
|
+
|
6
|
+
Copyright (C) 2006 Vincent Fourmond
|
7
|
+
|
8
|
+
This program is free software; you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU General Library Public License as published
|
10
|
+
by the Free Software Foundation; either version 2 of the License, or
|
11
|
+
(at your option) any later version.
|
12
|
+
|
13
|
+
This program is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU Library General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU Library General Public License
|
19
|
+
along with this program; if not, write to the Free Software
|
20
|
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
+
|
22
|
+
**********************************************************************/
|
23
|
+
|
24
|
+
/* This file provides two functions: store_double and get_double, which
|
25
|
+
can be used in a 'safe' way to store doubles and retrive them
|
26
|
+
in a hopefully platform-independent form. However, it just
|
27
|
+
stores it without regards to that if ieee754.h isn't found...
|
28
|
+
*/
|
29
|
+
|
30
|
+
#ifndef _DOUBLE_H
|
31
|
+
#define _DOUBLE_H
|
32
|
+
|
33
|
+
#define STORE_LOWER_BYTE(a,p) do {\
|
34
|
+
*(p++) = (a) & 0xFF; (a) >>= 8; }\
|
35
|
+
while(0)
|
36
|
+
#define STORE_UNSIGNED(a,p) for(i = 0; i < 4; i++) STORE_LOWER_BYTE(a,p);
|
37
|
+
#define GET_UNSIGNED(a,p) do { a = 0; for(i = 0; i < 4; i++) \
|
38
|
+
(a) |= *(p++) << (i * 8); } while (0)
|
39
|
+
|
40
|
+
#ifdef HAVE_IEEE754_H
|
41
|
+
#include <ieee754.h>
|
42
|
+
|
43
|
+
|
44
|
+
static inline void store_double(double a, unsigned char * p)
|
45
|
+
{
|
46
|
+
unsigned int tmp;
|
47
|
+
int i;
|
48
|
+
union ieee754_double d;
|
49
|
+
d.d = a;
|
50
|
+
/* we store it with lower bytes firts */
|
51
|
+
tmp = d.ieee.mantissa1;
|
52
|
+
STORE_UNSIGNED(tmp, p);
|
53
|
+
tmp = d.ieee.negative << 31 |
|
54
|
+
d.ieee.exponent << 20 |
|
55
|
+
d.ieee.mantissa0;
|
56
|
+
STORE_UNSIGNED(tmp, p);
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
static inline double get_double(const unsigned char * p)
|
61
|
+
{
|
62
|
+
unsigned int tmp;
|
63
|
+
int i;
|
64
|
+
union ieee754_double d;
|
65
|
+
GET_UNSIGNED(tmp, p);
|
66
|
+
d.ieee.mantissa1 = tmp;
|
67
|
+
GET_UNSIGNED(tmp, p);
|
68
|
+
d.ieee.mantissa0 = tmp & 0xFFFFF;
|
69
|
+
d.ieee.exponent = (tmp >> 20) & 0x7FF;
|
70
|
+
d.ieee.negative = (tmp >> 31) & 0x1;
|
71
|
+
return d.d;
|
72
|
+
}
|
73
|
+
|
74
|
+
#else
|
75
|
+
|
76
|
+
union basic_double{
|
77
|
+
double d;
|
78
|
+
struct {
|
79
|
+
unsigned int a:32;
|
80
|
+
unsigned int b:32;
|
81
|
+
} i;
|
82
|
+
};
|
83
|
+
|
84
|
+
static inline void store_double(double a, unsigned char * p)
|
85
|
+
{
|
86
|
+
union basic_double d;
|
87
|
+
int i;
|
88
|
+
d.d = a;
|
89
|
+
STORE_UNSIGNED(d.i.a, p);
|
90
|
+
STORE_UNSIGNED(d.i.b, p);
|
91
|
+
}
|
92
|
+
|
93
|
+
static inline double get_double(const unsigned char * p)
|
94
|
+
{
|
95
|
+
union basic_double d;
|
96
|
+
int i;
|
97
|
+
GET_UNSIGNED(d.i.a, p);
|
98
|
+
GET_UNSIGNED(d.i.b, p);
|
99
|
+
return d.d;
|
100
|
+
}
|
101
|
+
|
102
|
+
#endif /* HAVE_IEEE754_H */
|
103
|
+
|
104
|
+
#endif /* _DOUBLE_H */
|