Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/num_t/num_t.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2002-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* dss numeric type library
23
* bcd and ibm hacked from Griff Smith's ttu library
24
*
25
* Glenn Fowler
26
* AT&T Research
27
*/
28
29
#include <dsslib.h>
30
#include <hashpart.h>
31
#include <swap.h>
32
33
#define FIXED_EXTERNAL(f,format,value) { \
34
int i; \
35
f = (value)->number; \
36
if (i = (format)->fixedpoint) \
37
for (;;) \
38
{ \
39
if (i < elementsof(pow_10)) \
40
{ \
41
f *= pow_10[i]; \
42
break; \
43
} \
44
f *= pow_10[elementsof(pow_10) - 1]; \
45
i -= elementsof(pow_10); \
46
} \
47
}
48
49
#define FIXED_INTERNAL(f,w,value,format) { \
50
int i; \
51
f = (intmax_t)w; /* signed cast is msvc workaround */ \
52
if (i = (format)->fixedpoint) \
53
for (;;) \
54
{ \
55
if (i < elementsof(pow_10)) \
56
{ \
57
f /= pow_10[i]; \
58
break; \
59
} \
60
f /= pow_10[elementsof(pow_10) - 1]; \
61
i -= elementsof(pow_10); \
62
} \
63
(value)->number = f; \
64
}
65
66
static const Cxnumber_t pow_10[] =
67
{
68
1E0,
69
1E1,
70
1E2,
71
1E3,
72
1E4,
73
1E5,
74
1E6,
75
1E7,
76
1E8,
77
1E9,
78
1E10,
79
1E11,
80
1E12,
81
1E13,
82
1E14,
83
1E15,
84
1E16,
85
1E17,
86
1E18,
87
1E19,
88
1E20,
89
1E21,
90
1E22,
91
1E23,
92
1E24,
93
1E25,
94
1E26,
95
1E27,
96
1E28,
97
1E29,
98
1E30,
99
1E31,
100
};
101
102
/*
103
* bcd_pack[x] is the bcd byte for 0<=x<=99
104
*/
105
106
static const unsigned char bcd_pack[] =
107
{
108
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
109
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
110
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
111
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
112
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
113
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
114
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
115
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
116
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
117
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,
118
};
119
120
static ssize_t
121
bcd_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
122
{
123
register unsigned char* s = (unsigned char*)buf;
124
register unsigned char* e;
125
register Cxunsigned_t v;
126
Cxnumber_t f;
127
128
if (format->width > size)
129
return format->width;
130
if ((e = s + format->width - 1) < s)
131
return -1;
132
FIXED_EXTERNAL(f, format, value);
133
if (f < 0)
134
{
135
v = (Cxinteger_t)(-f);
136
*e = 0xD;
137
}
138
else
139
{
140
v = (Cxinteger_t)f;
141
*e = 0xC;
142
}
143
*e |= bcd_pack[(v % 10) * 10];
144
v /= 10;
145
while (e-- > s)
146
{
147
*e = bcd_pack[v % 100];
148
v /= 100;
149
}
150
return format->width;
151
}
152
153
/*
154
* bcd_unpack[x] is the decimal value for bcd byte x
155
* invalid codes convert to 0
156
*/
157
158
static const unsigned char bcd_unpack[] =
159
{
160
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
161
10,11,12,13,14,15,16,17,18,19, 0, 0, 0, 0, 0, 0,
162
20,21,22,23,24,25,26,27,28,29, 0, 0, 0, 0, 0, 0,
163
30,31,32,33,34,35,36,37,38,39, 0, 0, 0, 0, 0, 0,
164
40,41,42,43,44,45,46,47,48,49, 0, 0, 0, 0, 0, 0,
165
50,51,52,53,54,55,56,57,58,59, 0, 0, 0, 0, 0, 0,
166
60,61,62,63,64,65,66,67,68,69, 0, 0, 0, 0, 0, 0,
167
70,71,72,73,74,75,76,77,78,79, 0, 0, 0, 0, 0, 0,
168
80,81,82,83,84,85,86,87,88,89, 0, 0, 0, 0, 0, 0,
169
90,91,92,93,94,95,96,97,98,99, 0, 0, 0, 0, 0, 0,
170
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
171
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
172
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
173
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
174
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
175
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
176
};
177
178
/*
179
* bcd_negative[x]!=0 if bcd sign is negative
180
*/
181
182
static const unsigned char bcd_negative[] =
183
{
184
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
185
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
186
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
187
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
188
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
189
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
190
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
191
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
192
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
193
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
194
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
195
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
196
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
197
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
198
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
199
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
200
};
201
202
static ssize_t
203
bcd_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
204
{
205
register unsigned char* s = (unsigned char*)buf;
206
register unsigned char* e;
207
register Cxinteger_t w;
208
register unsigned const char* p;
209
Cxnumber_t f;
210
211
if (format->width > size)
212
return format->width;
213
w = 0;
214
p = bcd_unpack;
215
e = s + format->width - 1;
216
while (s < e && !*s)
217
s++;
218
switch (e - s)
219
{
220
case 21: w *= 100; w += p[*s++];
221
case 20: w *= 100; w += p[*s++];
222
case 19: w *= 100; w += p[*s++];
223
case 18: w *= 100; w += p[*s++];
224
case 17: w *= 100; w += p[*s++];
225
case 16: w *= 100; w += p[*s++];
226
case 15: w *= 100; w += p[*s++];
227
case 14: w *= 100; w += p[*s++];
228
case 13: w *= 100; w += p[*s++];
229
case 12: w *= 100; w += p[*s++];
230
case 11: w *= 100; w += p[*s++];
231
case 10: w *= 100; w += p[*s++];
232
case 9: w *= 100; w += p[*s++];
233
case 8: w *= 100; w += p[*s++];
234
case 7: w *= 100; w += p[*s++];
235
case 6: w *= 100; w += p[*s++];
236
case 5: w *= 100; w += p[*s++];
237
case 4: w *= 100; w += p[*s++];
238
case 3: w *= 100; w += p[*s++];
239
case 2: w *= 100; w += p[*s++];
240
case 1: w *= 100; w += p[*s++];
241
case 0: w *= 10; w += p[*s >> 4];
242
case -1:if (bcd_negative[*s]) w = -w;
243
}
244
FIXED_INTERNAL(f, w, &ret->value, format);
245
return format->width;
246
}
247
248
static ssize_t
249
be_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
250
{
251
register unsigned char* s = (unsigned char*)buf;
252
register unsigned char* e;
253
register unsigned char* u;
254
register Cxunsigned_t v;
255
_ast_flt4_t f4;
256
_ast_flt8_t f8;
257
Cxnumber_t f;
258
259
if (format->width > size)
260
return format->width;
261
e = s + format->width;
262
FIXED_EXTERNAL(f, format, value);
263
if (format->flags & CX_FLOAT)
264
{
265
switch (format->width)
266
{
267
case 4:
268
f4 = f;
269
u = (unsigned char*)&f4;
270
break;
271
case 8:
272
f8 = f;
273
u = (unsigned char*)&f8;
274
break;
275
}
276
#if _ast_intswap
277
swapmem(_ast_intswap, u, s, format->width);
278
#else
279
while (s < e)
280
*s++ = *u++;
281
#endif
282
}
283
else
284
{
285
v = (Cxinteger_t)f;
286
while (e > s)
287
{
288
*--e = v & 0xff;
289
v >>= 8;
290
}
291
}
292
return format->width;
293
}
294
295
static ssize_t
296
be_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
297
{
298
register unsigned char* s = (unsigned char*)buf;
299
register unsigned char* e;
300
register unsigned char* u;
301
register Cxunsigned_t v;
302
_ast_flt4_t f4;
303
_ast_flt8_t f8;
304
Cxnumber_t f;
305
306
if (format->width > size)
307
return format->width;
308
e = s + format->width;
309
if (format->flags & CX_FLOAT)
310
{
311
switch (format->width)
312
{
313
case 4:
314
u = (unsigned char*)&f4;
315
#if _ast_intswap
316
swapmem(_ast_intswap, u, s, format->width);
317
#else
318
while (s < e)
319
*u++ = *s++;
320
#endif
321
ret->value.number = f4;
322
break;
323
case 8:
324
u = (unsigned char*)&f8;
325
#if _ast_intswap
326
swapmem(_ast_intswap, u, s, format->width);
327
#else
328
while (s < e)
329
*u++ = *s++;
330
#endif
331
ret->value.number = f8;
332
break;
333
}
334
}
335
else
336
{
337
v = 0;
338
while (s < e)
339
{
340
v <<= 8;
341
v |= *s++;
342
}
343
FIXED_INTERNAL(f, v, &ret->value, format);
344
}
345
return format->width;
346
}
347
348
/*
349
* hash/rand -- hashed/random field -- handy for obfuscating sensitive data
350
*/
351
352
typedef struct
353
{
354
Cxunsigned_t hash;
355
int rand;
356
int seed;
357
} Hash_t;
358
359
static const char lower_hash[] = "abcdefghijklmnopqrstuvwxyz";
360
static const char upper_hash[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
361
static const char digit_hash[] = "0123456789";
362
363
extern time_t time(time_t*);
364
365
static void*
366
hash_init(void* data, Cxdisc_t* disc)
367
{
368
register Cxtype_t* type = (Cxtype_t*)data;
369
register const char* s;
370
register int n;
371
register Cxunsigned_t h;
372
register Hash_t* hp;
373
374
if (!(hp = newof(0, Hash_t, 1, 0)))
375
return 0;
376
h = 0;
377
for (s = type->name; n = *s++;)
378
HASHPART(h, n);
379
h ^= (Cxunsigned_t)time(NiL) ^ (((Cxunsigned_t)getpid()) << (h & 077));
380
for (n = ((h >> 7) & 077) | 0100; n > 0; n--)
381
HASHPART(h, n);
382
hp->hash = h;
383
hp->rand = type->name[0] == 'r';
384
hp->seed = 0;
385
return hp;
386
}
387
388
static ssize_t
389
hash_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
390
{
391
Hash_t* hp = (Hash_t*)type->data;
392
register unsigned char* s;
393
register unsigned char* e;
394
register unsigned char* t;
395
register int c;
396
register Cxunsigned_t h;
397
398
if (!hp->seed)
399
{
400
hp->seed = 1;
401
if (CXDETAILS(details, format, type, 0))
402
hp->hash = strtoul(details, NiL, 0);
403
}
404
if (value->string.size > size)
405
return value->string.size;
406
s = (unsigned char*)value->string.data;
407
e = s + value->string.size;
408
t = (unsigned char*)buf;
409
h = hp->hash;
410
while (s < e)
411
{
412
c = *s++;
413
HASHPART(h, c);
414
if (islower(c))
415
c = lower_hash[h % (sizeof(lower_hash) - 1)];
416
else if (isupper(c))
417
c = upper_hash[h % (sizeof(upper_hash) - 1)];
418
else if (c != '+' && c != '-' && c != '_' && c != '.' && c != ' ')
419
c = digit_hash[h % (sizeof(digit_hash) - 1)];
420
*t++ = c;
421
}
422
if (hp->rand)
423
hp->hash = h;
424
return value->string.size;
425
}
426
427
static ssize_t
428
hash_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
429
{
430
Hash_t* hp = (Hash_t*)type->data;
431
register unsigned char* s;
432
register unsigned char* e;
433
register unsigned char* t;
434
register int c;
435
register Cxunsigned_t h;
436
437
if (format->width > size)
438
return format->width;
439
if (!hp->seed)
440
{
441
hp->seed = 1;
442
if (CXDETAILS(details, format, type, 0))
443
hp->hash = strtoul(details, NiL, 0);
444
}
445
if (!(t = vmnewof(vm, 0, unsigned char, format->width, 1)))
446
return -1;
447
ret->value.string.data = (char*)t;
448
ret->value.string.size = format->width;
449
s = (unsigned char*)buf;
450
e = s + size;
451
h = hp->hash;
452
while (s < e)
453
{
454
c = *s++;
455
HASHPART(h, c);
456
if (islower(c))
457
c = lower_hash[h % (sizeof(lower_hash) - 1)];
458
else if (isupper(c))
459
c = upper_hash[h % (sizeof(upper_hash) - 1)];
460
else if (c != '+' && c != '-' && c != '_' && c != '.' && c != ' ')
461
c = digit_hash[h % (sizeof(digit_hash) - 1)];
462
*t++ = c;
463
}
464
if (hp->rand)
465
hp->hash = h;
466
return format->width;
467
}
468
469
/*
470
* base 100 integers
471
*/
472
473
static const unsigned char heka_unpack[UCHAR_MAX+1] =
474
{
475
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
476
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
477
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
478
0, 0, 0,
479
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
480
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
481
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
482
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
483
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
484
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
485
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
486
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
487
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
488
90, 0, 91, 92, 0, 0, 0, 0, 0, 0,
489
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
490
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
491
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
492
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
493
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
494
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
495
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
496
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
497
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
498
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
499
0, 0, 0, 0, 0,
500
0, 0, 0, 93, 94, 95, 96, 97, 98, 99
501
};
502
503
static ssize_t
504
heka_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
505
{
506
register unsigned char* s = (unsigned char*)buf;
507
register unsigned char* e = s + format->width;
508
register Cxunsigned_t u;
509
Cxnumber_t f;
510
int neg;
511
512
if (format->width > size)
513
return format->width;
514
e = s + format->width;
515
if (*s == '-')
516
{
517
s++;
518
neg = 1;
519
}
520
else
521
{
522
if (*s == '+')
523
s++;
524
neg = 0;
525
}
526
u = 0;
527
while (s < e)
528
u = u * 100 + heka_unpack[*s++];
529
FIXED_INTERNAL(f, u, &ret->value, format);
530
if (neg)
531
ret->value.number = -ret->value.number;
532
return 0;
533
}
534
535
static const unsigned char heka_pack[100] =
536
{
537
33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
538
43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
539
53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
540
63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
541
73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
542
83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
543
93, 94, 95, 96, 97, 98, 99,100,101,102,
544
103,104,105,106,107,108,109,110,111,112,
545
113,114,115,116,117,118,119,120,121,122,
546
123,125,126,241,242,243,244,245,246,247,
547
};
548
549
static ssize_t
550
heka_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
551
{
552
register unsigned char* s;
553
register unsigned char* t;
554
register unsigned char* e;
555
register ssize_t c;
556
register Cxunsigned_t u;
557
Cxnumber_t f;
558
int neg;
559
unsigned char tmp[128];
560
561
FIXED_EXTERNAL(f, format, value);
562
if (f >= 0 || (format->flags & CX_UNSIGNED))
563
{
564
u = (Cxinteger_t)f;
565
neg = 0;
566
}
567
else
568
{
569
u = (Cxinteger_t)(-f);
570
neg = 1;
571
}
572
s = t = &tmp[elementsof(tmp) - 1];
573
if (u == 0)
574
*--t = heka_pack[0];
575
else
576
while (u > 0)
577
{
578
*--t = heka_pack[u % 100];
579
u /= 100;
580
}
581
if ((c = format->width) > 0 && c < (elementsof(tmp) - 1))
582
{
583
e = s - c + 1;
584
c = heka_pack[0];
585
while (t > e)
586
*--t = c;
587
}
588
if (!(format->flags & CX_UNSIGNED))
589
*--t = neg ? '-' : '+';
590
if ((c = s - t) > size)
591
return c;
592
s = (unsigned char*)buf;
593
switch (c)
594
{
595
default:memcpy(s, t, c); break;
596
case 7: *s++ = *t++;
597
case 6: *s++ = *t++;
598
case 5: *s++ = *t++;
599
case 4: *s++ = *t++;
600
case 3: *s++ = *t++;
601
case 2: *s++ = *t++;
602
case 1: *s++ = *t++;
603
}
604
return c;
605
}
606
607
/*
608
* positive exponent values for IBM 370 floating point
609
*/
610
611
#if DBL_MAX_10_EXP > 37
612
613
#define IBM_FP_HI 7.23700557733226210e+75
614
#define IBM_FP_LO 5.39760534693402789e-79
615
616
static const double ibm_exp[] =
617
{
618
8.63616855509444463e-78, 1.38178696881511114e-76,
619
2.21085915010417782e-75, 3.53737464016668452e-74,
620
5.65979942426669523e-73, 9.05567907882671237e-72,
621
1.44890865261227398e-70, 2.31825384417963837e-69,
622
3.70920615068742139e-68, 5.93472984109987422e-67,
623
9.49556774575979875e-66, 1.51929083932156780e-64,
624
2.43086534291450848e-63, 3.88938454866321357e-62,
625
6.22301527786114171e-61, 9.95682444457782673e-60,
626
1.59309191113245228e-58, 2.54894705781192364e-57,
627
4.07831529249907783e-56, 6.52530446799852453e-55,
628
1.04404871487976392e-53, 1.67047794380762228e-52,
629
2.67276471009219565e-51, 4.27642353614751303e-50,
630
6.84227765783602085e-49, 1.09476442525376334e-47,
631
1.75162308040602134e-46, 2.80259692864963414e-45,
632
4.48415508583941463e-44, 7.17464813734306340e-43,
633
1.14794370197489014e-41, 1.83670992315982423e-40,
634
2.93873587705571877e-39, 4.70197740328915003e-38,
635
7.52316384526264005e-37, 1.20370621524202241e-35,
636
1.92592994438723585e-34, 3.08148791101957736e-33,
637
4.93038065763132378e-32, 7.88860905221011805e-31,
638
1.26217744835361890e-29, 2.01948391736579022e-28,
639
3.23117426778526435e-27, 5.16987882845642297e-26,
640
8.27180612553027675e-25, 1.32348898008484430e-23,
641
2.11758236813575085e-22, 3.38813178901720136e-21,
642
5.42101086242752217e-20, 8.67361737988403547e-19,
643
1.38777878078144568e-17, 2.22044604925031308e-16,
644
3.55271367880050093e-15, 5.68434188608080149e-14,
645
9.09494701772928238e-13, 1.45519152283668518e-11,
646
2.32830643653869629e-10, 3.72529029846191406e-09,
647
5.96046447753906250e-08, 9.53674316406250000e-07,
648
1.52587890625000000e-05, 2.44140625000000000e-04,
649
3.90625000000000000e-03, 6.25000000000000000e-02,
650
1.00000000000000000e+00, 1.60000000000000000e+01,
651
2.56000000000000000e+02, 4.09600000000000000e+03,
652
6.55360000000000000e+04, 1.04857600000000000e+06,
653
1.67772160000000000e+07, 2.68435456000000000e+08,
654
4.29496729600000000e+09, 6.87194767360000000e+10,
655
1.09951162777600000e+12, 1.75921860444160000e+13,
656
2.81474976710656000e+14, 4.50359962737049600e+15,
657
7.20575940379279360e+16, 1.15292150460684700e+18,
658
1.84467440737095516e+19, 2.95147905179352826e+20,
659
4.72236648286964521e+21, 7.55578637259143234e+22,
660
1.20892581961462920e+24, 1.93428131138340668e+25,
661
3.09485009821345069e+26, 4.95176015714152110e+27,
662
7.92281625142643376e+28, 1.26765060022822940e+30,
663
2.02824096036516704e+31, 3.24518553658426727e+32,
664
5.19229685853482763e+33, 8.30767497365572421e+34,
665
1.32922799578491587e+36, 2.12676479325586540e+37,
666
3.40282366920938463e+38, 5.44451787073501542e+39,
667
8.71122859317602466e+40, 1.39379657490816395e+42,
668
2.23007451985306231e+43, 3.56811923176489970e+44,
669
5.70899077082383952e+45, 9.13438523331814324e+46,
670
1.46150163733090292e+48, 2.33840261972944467e+49,
671
3.74144419156711147e+50, 5.98631070650737835e+51,
672
9.57809713041180536e+52, 1.53249554086588886e+54,
673
2.45199286538542217e+55, 3.92318858461667548e+56,
674
6.27710173538668076e+57, 1.00433627766186892e+59,
675
1.60693804425899028e+60, 2.57110087081438444e+61,
676
4.11376139330301511e+62, 6.58201822928482417e+63,
677
1.05312291668557190e+65, 1.68499666669691499e+66,
678
2.69599466671506398e+67, 4.31359146674410237e+68,
679
6.90174634679056379e+69, 1.10427941548649021e+71,
680
1.76684706477838433e+72, 2.82695530364541493e+73,
681
4.52312848583266388e+74, 7.23700557733226210e+75,
682
};
683
684
#else
685
686
/*
687
* full ibm range not supported
688
*/
689
690
#define IBM_FP_HI 1.70141183460469230e+38
691
#define IBM_FP_LO 4.70197740328915000e-38
692
693
static const double ibm_exp[] =
694
{
695
IBM_FP_LO, IBM_FP_LO,
696
IBM_FP_LO, IBM_FP_LO,
697
IBM_FP_LO, IBM_FP_LO,
698
IBM_FP_LO, IBM_FP_LO,
699
IBM_FP_LO, IBM_FP_LO,
700
IBM_FP_LO, IBM_FP_LO,
701
IBM_FP_LO, IBM_FP_LO,
702
IBM_FP_LO, IBM_FP_LO,
703
IBM_FP_LO, IBM_FP_LO,
704
IBM_FP_LO, IBM_FP_LO,
705
IBM_FP_LO, IBM_FP_LO,
706
IBM_FP_LO, IBM_FP_LO,
707
IBM_FP_LO, IBM_FP_LO,
708
IBM_FP_LO, IBM_FP_LO,
709
IBM_FP_LO, IBM_FP_LO,
710
IBM_FP_LO, IBM_FP_LO,
711
IBM_FP_LO, IBM_FP_LO,
712
7.52316384526264005e-37, 1.20370621524202241e-35,
713
1.92592994438723585e-34, 3.08148791101957736e-33,
714
4.93038065763132378e-32, 7.88860905221011805e-31,
715
1.26217744835361890e-29, 2.01948391736579022e-28,
716
3.23117426778526435e-27, 5.16987882845642297e-26,
717
8.27180612553027675e-25, 1.32348898008484430e-23,
718
2.11758236813575085e-22, 3.38813178901720136e-21,
719
5.42101086242752217e-20, 8.67361737988403547e-19,
720
1.38777878078144568e-17, 2.22044604925031308e-16,
721
3.55271367880050093e-15, 5.68434188608080149e-14,
722
9.09494701772928238e-13, 1.45519152283668518e-11,
723
2.32830643653869629e-10, 3.72529029846191406e-09,
724
5.96046447753906250e-08, 9.53674316406250000e-07,
725
1.52587890625000000e-05, 2.44140625000000000e-04,
726
3.90625000000000000e-03, 6.25000000000000000e-02,
727
1.00000000000000000e+00, 1.60000000000000000e+01,
728
2.56000000000000000e+02, 4.09600000000000000e+03,
729
6.55360000000000000e+04, 1.04857600000000000e+06,
730
1.67772160000000000e+07, 2.68435456000000000e+08,
731
4.29496729600000000e+09, 6.87194767360000000e+10,
732
1.09951162777600000e+12, 1.75921860444160000e+13,
733
2.81474976710656000e+14, 4.50359962737049600e+15,
734
7.20575940379279360e+16, 1.15292150460684700e+18,
735
1.84467440737095516e+19, 2.95147905179352826e+20,
736
4.72236648286964521e+21, 7.55578637259143234e+22,
737
1.20892581961462920e+24, 1.93428131138340668e+25,
738
3.09485009821345069e+26, 4.95176015714152110e+27,
739
7.92281625142643376e+28, 1.26765060022822940e+30,
740
2.02824096036516704e+31, 3.24518553658426727e+32,
741
5.19229685853482763e+33, 8.30767497365572421e+34,
742
1.32922799578491587e+36, 2.12676479325586540e+37,
743
IBM_FP_HI, IBM_FP_HI,
744
IBM_FP_HI, IBM_FP_HI,
745
IBM_FP_HI, IBM_FP_HI,
746
IBM_FP_HI, IBM_FP_HI,
747
IBM_FP_HI, IBM_FP_HI,
748
IBM_FP_HI, IBM_FP_HI,
749
IBM_FP_HI, IBM_FP_HI,
750
IBM_FP_HI, IBM_FP_HI,
751
IBM_FP_HI, IBM_FP_HI,
752
IBM_FP_HI, IBM_FP_HI,
753
IBM_FP_HI, IBM_FP_HI,
754
IBM_FP_HI, IBM_FP_HI,
755
IBM_FP_HI, IBM_FP_HI,
756
IBM_FP_HI, IBM_FP_HI,
757
IBM_FP_HI, IBM_FP_HI,
758
IBM_FP_HI, IBM_FP_HI,
759
};
760
761
#endif
762
763
#define FLOOR(x) ((Cxinteger_t)(x))
764
765
static ssize_t
766
ibm_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
767
{
768
register unsigned char* s = (unsigned char*)buf;
769
register unsigned int lo;
770
register unsigned int hi;
771
register unsigned int ex;
772
register double f;
773
int negative;
774
Cxinteger_t hi3;
775
Cxinteger_t md2;
776
Cxinteger_t lo2;
777
778
if (format->width > size)
779
return format->width;
780
if (negative = (f = value->number) < 0.0)
781
f = -f;
782
switch (format->width)
783
{
784
case 4:
785
if (f < IBM_FP_LO)
786
s[0] = s[1] = s[2] = s[3] = 0x00;
787
else
788
{
789
if (f > IBM_FP_HI)
790
f = IBM_FP_HI;
791
792
/*
793
* find the closest exponent in ibm_exp[]
794
*/
795
796
lo = 0;
797
hi = elementsof(ibm_exp) - 1;
798
while (lo != hi + 1)
799
{
800
ex = lo + ((hi - lo) >> 1);
801
if (ibm_exp[ex] < f)
802
lo = ex + 1;
803
else
804
hi = ex - 1;
805
}
806
if (ibm_exp[ex] < f)
807
ex++;
808
809
/*
810
* scale by the exponent to reduce
811
* to the range 0.0625 -> 0.9999...
812
*/
813
814
f /= ibm_exp[ex];
815
816
/*
817
* extract the fraction bits as integers
818
*/
819
820
f *= (double)0x1000000;
821
hi3 = FLOOR(f + 0.5);
822
823
/*
824
* correct for overflow
825
*/
826
827
if (hi3 > 0xFFFFFF)
828
{
829
hi3 = 0x100000;
830
ex++;
831
}
832
if (ex > 0x7F)
833
{
834
ex = 0x7F;
835
hi3 = 0xFFFFFF;
836
}
837
838
/*
839
* set the sign bit
840
*/
841
842
if (negative)
843
ex |= 0x80;
844
845
/*
846
* done
847
*/
848
849
s[0] = ex;
850
s[1] = hi3 >> 16;
851
s[2] = (hi3 >> 8) & 0xFF;
852
s[3] = hi3 & 0xFF;
853
}
854
return 4;
855
case 8:
856
if (f < IBM_FP_LO)
857
s[0] = s[1] = s[2] = s[3] = s[4] = s[5] = s[6] = s[7] = 0x00;
858
else
859
{
860
if (f > IBM_FP_HI)
861
f = IBM_FP_HI;
862
863
/*
864
* find the closest exponent in ibm_exp[]
865
*/
866
867
lo = 0;
868
hi = elementsof(ibm_exp) - 1;
869
while (lo != hi + 1)
870
{
871
ex = lo + ((hi - lo) >> 1);
872
if (ibm_exp[ex] < f)
873
lo = ex + 1;
874
else
875
hi = ex - 1;
876
}
877
if (ibm_exp[ex] < f)
878
ex++;
879
880
/*
881
* scale by the exponent to reduce
882
* to the range 0.0625 -> 0.9999...
883
*/
884
885
f /= ibm_exp[ex];
886
887
/*
888
* extract the fraction bits as integers
889
*/
890
891
f *= (double)0x1000000;
892
hi3 = FLOOR(f);
893
f -= hi3;
894
f *= (double)0x10000;
895
md2 = FLOOR(f);
896
f -= md2;
897
f *= (double)0x10000;
898
lo2 = FLOOR(f + 0.5);
899
900
/*
901
* correct for overflow
902
*/
903
904
if (lo2 > 0xFFFF)
905
{
906
lo2 -= 0x10000;
907
md2++;
908
}
909
if (md2 > 0xFFFF)
910
{
911
md2 -= 0x10000;
912
hi3++;
913
}
914
if (hi3 > 0xFFFFFF)
915
{
916
hi3 = 0x100000;
917
ex++;
918
}
919
if (ex > 0x7F)
920
{
921
ex = 0x7F;
922
hi3 = 0xFFFFFF;
923
md2 = 0xFFFF;
924
lo2 = 0xFFFF;
925
}
926
927
/*
928
* set the sign bit
929
*/
930
931
if (negative)
932
ex |= 0x80;
933
934
/*
935
* done
936
*/
937
938
s[0] = ex;
939
s[1] = hi3 >> 16;
940
s[2] = (hi3 >> 8) & 0xFF;
941
s[3] = hi3 & 0xFF;
942
s[4] = md2 >> 8;
943
s[5] = md2 & 0xFF;
944
s[6] = lo2 >> 8;
945
s[7] = lo2 & 0xFF;
946
}
947
return 8;
948
}
949
return -1;
950
}
951
952
static ssize_t
953
ibm_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
954
{
955
register unsigned char* s = (unsigned char*)buf;
956
register Cxinteger_t i;
957
register double f;
958
959
if (format->width > size)
960
return format->width;
961
switch (format->width)
962
{
963
case 4:
964
i = (s[1] << 16)
965
| (s[2] << 8)
966
| s[3];
967
f = i * (1.0 / 0x1000000) * ((s[0] < 0x80) ? ibm_exp[s[0]] : -ibm_exp[s[0] & 0x7F]);
968
ret->value.number = f;
969
return 4;
970
case 8:
971
i = (s[1] << 16)
972
| (s[2] << 8)
973
| s[3];
974
f = i * (1.0 / 0x1000000);
975
i = (s[4] << 8)
976
| s[5];
977
f += i * ((1.0 / 0x1000000) / (double)0x10000);
978
i = (s[6] << 8)
979
| s[7];
980
f += i * (((1.0 / 0x1000000) / (double)0x10000) / (double)0x10000);
981
f *= (s[0] < 0x80) ? ibm_exp[s[0]] : -ibm_exp[s[0] & 0x7F];
982
ret->value.number = f;
983
return 8;
984
}
985
return -1;
986
}
987
988
static ssize_t
989
le_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
990
{
991
register unsigned char* s = (unsigned char*)buf;
992
register unsigned char* e;
993
register unsigned char* u;
994
register Cxunsigned_t v;
995
_ast_flt4_t f4;
996
_ast_flt8_t f8;
997
Cxnumber_t f;
998
999
if (format->width > size)
1000
return format->width;
1001
e = s + format->width;
1002
FIXED_EXTERNAL(f, format, value);
1003
if (format->flags & CX_FLOAT)
1004
{
1005
switch (format->width)
1006
{
1007
case 4:
1008
f4 = f;
1009
u = (unsigned char*)&f4;
1010
break;
1011
case 8:
1012
f8 = f;
1013
u = (unsigned char*)&f8;
1014
break;
1015
}
1016
#if _ast_intswap ^ 7
1017
swapmem(_ast_intswap ^ 7, u, s, format->width);
1018
#else
1019
while (s < e)
1020
*s++ = *u++;
1021
#endif
1022
}
1023
else
1024
{
1025
v = (Cxinteger_t)value->number;
1026
while (s < e)
1027
{
1028
*s++ = v & 0xff;
1029
v >>= 8;
1030
}
1031
}
1032
return format->width;
1033
}
1034
1035
static ssize_t
1036
le_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
1037
{
1038
register unsigned char* s = (unsigned char*)buf;
1039
register unsigned char* e;
1040
register unsigned char* u;
1041
register Cxunsigned_t v;
1042
_ast_flt4_t f4;
1043
_ast_flt8_t f8;
1044
Cxnumber_t f;
1045
1046
if (format->width > size)
1047
return format->width;
1048
e = s + format->width;
1049
if (format->flags & CX_FLOAT)
1050
{
1051
switch (format->width)
1052
{
1053
case 4:
1054
u = (unsigned char*)&f4;
1055
#if _ast_intswap ^ 7
1056
swapmem(_ast_intswap ^ 7, u, s, format->width);
1057
#else
1058
while (s < e)
1059
*u++ = *s++;
1060
#endif
1061
ret->value.number = f4;
1062
break;
1063
case 8:
1064
u = (unsigned char*)&f8;
1065
#if _ast_intswap ^ 7
1066
swapmem(_ast_intswap ^ 7, u, s, format->width);
1067
#else
1068
while (s < e)
1069
*u++ = *s++;
1070
#endif
1071
ret->value.number = f8;
1072
break;
1073
}
1074
}
1075
else
1076
{
1077
v = 0;
1078
while (e > s)
1079
{
1080
v <<= 8;
1081
v |= *--e;
1082
}
1083
FIXED_INTERNAL(f, v, &ret->value, format);
1084
}
1085
return format->width;
1086
}
1087
1088
static ssize_t
1089
sf_external(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxvalue_t* value, char* buf, size_t size, Cxdisc_t* disc)
1090
{
1091
register int r;
1092
register Cxinteger_t v;
1093
register Cxunsigned_t u;
1094
Cxnumber_t f;
1095
1096
FIXED_EXTERNAL(f, format, value);
1097
sfstrbuf(cx->buf, buf, size, 0);
1098
if (format->flags & CX_FLOAT)
1099
r = sfputd(cx->buf, f);
1100
else if (format->flags & CX_UNSIGNED)
1101
{
1102
v = f;
1103
u = v;
1104
r = sfputu(cx->buf, u);
1105
}
1106
else
1107
{
1108
v = f;
1109
r = sfputl(cx->buf, v);
1110
}
1111
if (r < 0)
1112
return size ? 2 * size : 8;
1113
return r;
1114
}
1115
1116
static ssize_t
1117
sf_internal(Cx_t* cx, Cxtype_t* type, const char* details, Cxformat_t* format, Cxoperand_t* ret, const char* buf, size_t size, Vmalloc_t* vm, Cxdisc_t* disc)
1118
{
1119
if (!size)
1120
return 4;
1121
sfstrbuf(cx->buf, (void*)buf, size, 0);
1122
if (format->flags & CX_FLOAT)
1123
ret->value.number = sfgetd(cx->buf);
1124
else if (format->flags & CX_UNSIGNED)
1125
ret->value.number = (Cxinteger_t)sfgetu(cx->buf);
1126
else
1127
ret->value.number = sfgetl(cx->buf);
1128
if (sferror(cx->buf))
1129
return size * 2;
1130
return sfstrtell(cx->buf);
1131
}
1132
1133
static Cxtype_t types[] =
1134
{
1135
{ "bcd_t", "Binary coded decimal.", CXH, (Cxtype_t*)"number", 0, bcd_external, bcd_internal, 0, 0, 0, 0, { 0, 0, CX_INTEGER } },
1136
{ "be_t", "Big endian binary.", CXH, (Cxtype_t*)"number", 0, be_external, be_internal, 0, 0, 0, 0, { 0, 0, CX_BINARY } },
1137
{ "hash_t", "Repeatable string hash.", CXH, (Cxtype_t*)"string", hash_init, hash_external, hash_internal, 0, 0, 0, 0, { 0, 0, CX_STRING } },
1138
{ "heka_t", "Base 100 binary integer.", CXH, (Cxtype_t*)"number", 0, heka_external, heka_internal, 0, 0, 0, 0, { 0, 0, CX_INTEGER } },
1139
{ "ibm_t", "IBM 4 and 8 byte floating point.", CXH, (Cxtype_t*)"number", 0, ibm_external, ibm_internal, 0, 0, 0, 0, { 0, 0, CX_FLOAT } },
1140
{ "le_t", "Little endian binary.", CXH, (Cxtype_t*)"number", 0, le_external, le_internal, 0, 0, 0, 0, { 0, 0, CX_BINARY } },
1141
{ "rand_t", "Non-repeatable pseudo-random string hash.", CXH, (Cxtype_t*)"string", hash_init, hash_external, hash_internal, 0, 0, 0, 0, { "The format details string is an optional initial pseudo-random seed number. The default is synthesized using current process/system characteristics.", 0, CX_STRING } },
1142
{ "sf_t", "sfio sfputd()/sfputl()/sfputu() encoding.", CXH, (Cxtype_t*)"number", 0, sf_external, sf_internal },
1143
{0}
1144
};
1145
1146
Dsslib_t dss_lib_num_t =
1147
{
1148
"num_t",
1149
"numeric type support"
1150
"[-?\n@(#)$Id: dss numeric type library (AT&T Research) 2008-06-11 $\n]"
1151
USAGE_LICENSE,
1152
CXH,
1153
0,
1154
0,
1155
&types[0],
1156
};
1157
1158