1 /* This code is part of the tng compression routines.
2 *
3 * Written by Daniel Spangberg
4 * Copyright (c) 2010, 2013, The GROMACS development team.
5 *
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the Revised BSD License.
9 */
10
11 #include <stdio.h>
12 #include <math.h>
13 #include "../../include/compression/fixpoint.h"
14
15 #define MAX32BIT 4294967295UL
16 #define MAX31BIT 2147483647UL
17 #define SIGN32BIT 2147483648UL
18
19 /* Conversion routines from / to double precision */
20
21 /* Positive double to 32 bit fixed point value */
Ptngc_ud_to_fix_t(double d,const double max)22 fix_t Ptngc_ud_to_fix_t(double d, const double max)
23 {
24 fix_t val;
25 if (d<0.)
26 d=0.;
27 if (d>max)
28 d=max;
29 val=(fix_t)(MAX32BIT*(d/max));
30 if (val>MAX32BIT)
31 val=MAX32BIT;
32 return val;
33 }
34
35 /* double to signed 32 bit fixed point value */
Ptngc_d_to_fix_t(double d,const double max)36 fix_t Ptngc_d_to_fix_t(double d, const double max)
37 {
38 fix_t val;
39 int sign=0;
40 if (d<0.)
41 {
42 sign=1;
43 d=-d;
44 }
45 if (d>max)
46 d=max;
47 val=(fix_t)(MAX31BIT*(d/max));
48 if (val>MAX31BIT)
49 val=MAX31BIT;
50 if (sign)
51 val|=SIGN32BIT;
52 return val;
53 }
54
55
56 /* 32 bit fixed point value to positive double */
Ptngc_fix_t_to_ud(fix_t f,const double max)57 double Ptngc_fix_t_to_ud(fix_t f, const double max)
58 {
59 return (double)f*(max/MAX32BIT);
60 }
61
62 /* signed 32 bit fixed point value to double */
Ptngc_fix_t_to_d(fix_t f,const double max)63 double Ptngc_fix_t_to_d(fix_t f, const double max)
64 {
65 int sign=0;
66 double d;
67 if (f&SIGN32BIT)
68 {
69 sign=1;
70 f&=MAX31BIT;
71 }
72 d=(double)f*(max/MAX31BIT);
73 if (sign)
74 d=-d;
75 return d;
76 }
77
78
79 /* Convert a floating point variable to two 32 bit integers with range
80 -2.1e9 to 2.1e9 and precision to somewhere around 1e-9. */
Ptngc_d_to_i32x2(double d,fix_t * hi,fix_t * lo)81 void Ptngc_d_to_i32x2(double d, fix_t *hi, fix_t *lo)
82 {
83 int sign=0;
84 double frac;
85 double ent;
86 fix_t val,vallo;
87 if (d<0.)
88 {
89 sign=1;
90 d=-d;
91 }
92 /* First the integer part */
93 ent=floor(d);
94 /* Then the fractional part */
95 frac=d-ent;
96
97 val=(fix_t)ent;
98 if (sign)
99 val|=SIGN32BIT;
100
101 vallo=Ptngc_ud_to_fix_t(frac,1.);
102
103 *hi=val;
104 *lo=vallo;
105 }
106
107 /* Convert two 32 bit integers to a floating point variable
108 -2.1e9 to 2.1e9 and precision to somewhere around 1e-9. */
Ptngc_i32x2_to_d(fix_t hi,fix_t lo)109 double Ptngc_i32x2_to_d(fix_t hi, fix_t lo)
110 {
111 double ent,frac=0.;
112 double val=0.;
113 int sign=0;
114 if (hi&SIGN32BIT)
115 {
116 sign=1;
117 hi&=MAX31BIT;
118 }
119 ent=(double)hi;
120 frac=Ptngc_fix_t_to_ud(lo,1.);
121 val=ent+frac;
122 if (sign)
123 val=-val;
124 return val;
125 }
126
127