Lossy Floating point: libdroundfast
This commit is contained in:
61
TurboPFor-Integer-Compression/lib/ext/libdroundfast.c
Normal file
61
TurboPFor-Integer-Compression/lib/ext/libdroundfast.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, CNES.
|
||||||
|
*
|
||||||
|
* This source code is licensed under MIT-style license (found in the
|
||||||
|
* COPYING file in the root directory of this source tree).
|
||||||
|
*/
|
||||||
|
//https://github.com/CNES/Digit_Rounding/blob/master/libdround/src/libdroundfast.c
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define LOG2_10 3.321928095 // log2(10)
|
||||||
|
#define LOG10_2 0.301029996 // log10(2)
|
||||||
|
|
||||||
|
#define SIGN(x) ( (x<0) ? -1 : 1 )
|
||||||
|
|
||||||
|
const float TABLE[5][2] = {
|
||||||
|
{0.6, -LOG10_2},
|
||||||
|
{0.7,-0.221848749},
|
||||||
|
{0.8,-0.154901959},
|
||||||
|
{0.9,-0.096910013},
|
||||||
|
{1.0,-0.045757490},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Round the float value keeping nsd significant digits.
|
||||||
|
* Fast method that does not uses log10() function.
|
||||||
|
*/
|
||||||
|
double droundFast(double v, int nsd)
|
||||||
|
{
|
||||||
|
// compute the number of digits before the decimal point of the input floating-point value v
|
||||||
|
// The value v is interpreted as v = 10^d + eps = 2^e + m
|
||||||
|
// with 0 <= m < 0.5
|
||||||
|
int e;
|
||||||
|
double m = frexp(v, &e); // return the binary exponent e of the input value v = 2^e + m with 0 <= m < 0.5
|
||||||
|
|
||||||
|
// =============
|
||||||
|
// --- tabulated method ---
|
||||||
|
// tabulate the LOG10(m)
|
||||||
|
int i = 0;
|
||||||
|
while (TABLE[i][0] < m)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
float log10m = TABLE[i][1];
|
||||||
|
|
||||||
|
// --- low precision method ---
|
||||||
|
// float log10m = -LOG10_2;
|
||||||
|
// =============
|
||||||
|
|
||||||
|
// convert the binary exponent to a number of digits: d = floor(e*log10(2) + log10(m)) + 1
|
||||||
|
int d = (int) floor(e*LOG10_2 + log10m) + 1;
|
||||||
|
|
||||||
|
// compute the power of the quantization step: q = 2^p
|
||||||
|
int p = (int) floor(LOG2_10 * (d - nsd));
|
||||||
|
// compute quantization step: q = 2^p
|
||||||
|
double q = ldexp(1, p);
|
||||||
|
|
||||||
|
// apply the quantization step depending on the bias
|
||||||
|
return SIGN(v) * (floor(fabs(v) / q) + 0.5) * q;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user