412 |
free (w); |
free (w); |
413 |
} |
} |
414 |
|
|
415 |
/* Base-30 conversion. */ |
/* Base-30 conversion. |
416 |
|
|
417 |
|
Portable files represent numbers in base-30 format, so we need |
418 |
|
to be able to convert real and integer number to that base. |
419 |
|
Older versions of PSPP used libgmp to do so, but this added a |
420 |
|
big library dependency to do just one thing. Now we do it |
421 |
|
ourselves internally. |
422 |
|
|
423 |
|
Important fact: base 30 is called "trigesimal". */ |
424 |
|
|
425 |
/* Conversion base. */ |
/* Conversion base. */ |
426 |
#define BASE 30 /* As an integer. */ |
#define BASE 30 /* As an integer. */ |
430 |
digits that a `long int' can hold. */ |
digits that a `long int' can hold. */ |
431 |
#define CHUNK_SIZE 6 |
#define CHUNK_SIZE 6 |
432 |
|
|
433 |
/* Yields the square of X. */ |
/* pow_tab[i] = pow (30, pow (2, i)) */ |
434 |
#define Q(X) ((X) * (X)) |
static long double pow_tab[16]; |
435 |
|
|
436 |
|
/* Initializes pow_tab[]. */ |
437 |
|
static void |
438 |
|
init_pow_tab (void) |
439 |
|
{ |
440 |
|
static bool did_init = false; |
441 |
|
long double power; |
442 |
|
size_t i; |
443 |
|
|
444 |
|
/* Only initialize once. */ |
445 |
|
if (did_init) |
446 |
|
return; |
447 |
|
did_init = true; |
448 |
|
|
449 |
|
/* Set each element of pow_tab[] until we run out of numerical |
450 |
|
range. */ |
451 |
|
i = 0; |
452 |
|
for (power = 30.0L; power < DBL_MAX; power *= power) |
453 |
|
{ |
454 |
|
assert (i < sizeof pow_tab / sizeof *pow_tab); |
455 |
|
pow_tab[i++] = power; |
456 |
|
} |
457 |
|
} |
458 |
|
|
459 |
/* Returns 30**EXPONENT, for 0 <= EXPONENT <= log30(DBL_MAX). */ |
/* Returns 30**EXPONENT, for 0 <= EXPONENT <= log30(DBL_MAX). */ |
460 |
static long double |
static long double |
461 |
pow30_nonnegative (int exponent) |
pow30_nonnegative (int exponent) |
462 |
{ |
{ |
|
/* pow_tab[i] = pow (30, pow (2, i)) */ |
|
|
static const long double pow_tab[] = |
|
|
{ |
|
|
LDBASE, |
|
|
Q (LDBASE), |
|
|
Q (Q (LDBASE)), |
|
|
Q (Q (Q (LDBASE))), |
|
|
Q (Q (Q (Q (LDBASE)))), |
|
|
Q (Q (Q (Q (Q (LDBASE))))), |
|
|
Q (Q (Q (Q (Q (Q (LDBASE)))))), |
|
|
Q (Q (Q (Q (Q (Q (Q (LDBASE))))))), |
|
|
Q (Q (Q (Q (Q (Q (Q (Q (LDBASE)))))))), |
|
|
Q (Q (Q (Q (Q (Q (Q (Q (Q (LDBASE))))))))), |
|
|
Q (Q (Q (Q (Q (Q (Q (Q (Q (Q (LDBASE)))))))))), |
|
|
Q (Q (Q (Q (Q (Q (Q (Q (Q (Q (Q (LDBASE))))))))))), |
|
|
}; |
|
|
|
|
463 |
long double power; |
long double power; |
464 |
int i; |
int i; |
465 |
|
|
652 |
/* Number of trigesimal places left to write into BUFFER. */ |
/* Number of trigesimal places left to write into BUFFER. */ |
653 |
int trigs_to_output; |
int trigs_to_output; |
654 |
|
|
655 |
|
init_pow_tab (); |
656 |
|
|
657 |
/* Handle special cases. */ |
/* Handle special cases. */ |
658 |
if (value == SYSMIS) |
if (value == SYSMIS) |
659 |
goto missing_value; |
goto missing_value; |