#include <float.h>
#include <limits.h>
#include <math.h>
static uint _t2(rev_encode_block, Scalar, DIMS)(zfp_stream* zfp, const Scalar* fblock);
static int
_t1(exponent, Scalar)(Scalar x)
{
int e = -EBIAS;
#ifdef ZFP_WITH_DAZ
if (x >= SCALAR_MIN)
FREXP(x, &e);
#else
if (x > 0) {
FREXP(x, &e);
e = MAX(e, 1 - EBIAS);
}
#endif
return e;
}
static int
_t1(exponent_block, Scalar)(const Scalar* p, uint n)
{
Scalar max = 0;
do {
Scalar f = FABS(*p++);
if (max < f)
max = f;
} while (--n);
return _t1(exponent, Scalar)(max);
}
static Scalar
_t1(quantize, Scalar)(Scalar x, int e)
{
return LDEXP(x, ((int)(CHAR_BIT * sizeof(Scalar)) - 2) - e);
}
static void
_t1(fwd_cast, Scalar)(Int* iblock, const Scalar* fblock, uint n, int emax)
{
Scalar s = _t1(quantize, Scalar)(1, emax);
do
*iblock++ = (Int)(s * *fblock++);
while (--n);
}
static uint
_t2(encode_block, Scalar, DIMS)(zfp_stream* zfp, const Scalar* fblock)
{
uint bits = 1;
int emax = _t1(exponent_block, Scalar)(fblock, BLOCK_SIZE);
int maxprec = precision(emax, zfp->maxprec, zfp->minexp, DIMS);
uint e = maxprec ? emax + EBIAS : 0;
if (e) {
cache_align_(Int iblock[BLOCK_SIZE]);
bits += EBITS;
stream_write_bits(zfp->stream, 2 * e + 1, bits);
_t1(fwd_cast, Scalar)(iblock, fblock, BLOCK_SIZE, emax);
bits += _t2(encode_block, Int, DIMS)(zfp->stream, zfp->minbits - bits, zfp->maxbits - bits, maxprec, iblock);
}
else {
stream_write_bit(zfp->stream, 0);
if (zfp->minbits > bits) {
stream_pad(zfp->stream, zfp->minbits - bits);
bits = zfp->minbits;
}
}
return bits;
}
size_t
_t2(zfp_encode_block, Scalar, DIMS)(zfp_stream* zfp, const Scalar* fblock)
{
return REVERSIBLE(zfp) ? _t2(rev_encode_block, Scalar, DIMS)(zfp, fblock) : _t2(encode_block, Scalar, DIMS)(zfp, fblock);
}