From Sven-Ola Tuecke <sven-ola@gmx.de>: add support for fixedpoint math
[olsrd.git] / src / fpm.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2008, Sven-Ola Tuecke (sven-ola@gmx.de)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41 #include <stdio.h>
42 #include <assert.h>
43 #include "fpm.h"
44
45 #if !defined(NDEBUG) && defined(USE_FPM)
46
47 fpm itofpm(int i)
48 {
49   fpm r;
50   assert(FPM_MIN <= i && i <= FPM_MAX);
51   r = (fpm)itofpm_def(i);
52   return r;
53 }
54
55 fpm ftofpm(float f)
56 {
57   fpm r;
58   assert(FPM_MIN <= (sfpm)f && (sfpm)f <= FPM_MAX);
59   r = (fpm)(sfpm)ftofpm_def(f);
60   return r;
61 }
62
63 int fpmtoi(fpm a)
64 {
65   int r = fpmtoi_def((sfpm)a);
66   return r;
67 }
68
69 float fpmtof(fpm a)
70 {
71   float r = fpmtof_def((sfpm)a);
72   return r;
73 }
74
75 fpm fpmadd(fpm a, fpm b)
76 {
77   fpm r;
78   assert(0 > (sfpm)a || 0 > (sfpm)b || FPM_INT_MAX - (sfpm)a >= (sfpm)b);
79   assert(0 <= (sfpm)a || 0 <= (sfpm)b || (sfpm)a >= FPM_INT_MIN - (sfpm)b);
80   r = (fpm)fpmadd_def((sfpm)a, (sfpm)b);
81   return r;
82 }
83
84 fpm fpmsub(fpm a, fpm b)
85 {
86   fpm r;
87   assert(0 > (sfpm)a || 0 <= (sfpm)b || (sfpm)a < FPM_INT_MAX + (sfpm)b);
88   assert(0 <= (sfpm)a || 0 > (sfpm)b || (sfpm)a >= FPM_INT_MIN + (sfpm)b);
89   r = (fpm)fpmsub_def((sfpm)a, (sfpm)b);
90   return r;
91 }
92
93 fpm fpmmul(fpm a, fpm b)
94 {
95   fpm r;
96   assert((0 < (sfpm)a) != (0 < (sfpm)b) || ((double)(sfpm)a) * ((double)(sfpm)b) <= (double)FPM_INT_MAX);
97   assert((0 < (sfpm)a) == (0 < (sfpm)b) || ((double)(sfpm)a) * ((double)(sfpm)b) >= (double)FPM_INT_MIN);
98   r = (fpm)fpmmul_def((sfpm)a, (sfpm)b);
99   return r;
100 }
101
102 fpm fpmdiv(fpm a, fpm b) {
103   fpm r;
104   assert(FPM_INT_MIN <= ((long long)(sfpm)a << FPM_BIT) && ((long long)(sfpm)a << FPM_BIT) <= FPM_INT_MAX);
105   r = (fpm)fpmdiv_def((sfpm)a, (sfpm)b);
106   return r;
107 }
108
109 fpm fpmimul(int a, fpm b)
110 {
111   fpm r;
112   assert((0 < a) != (0 < (sfpm)b) || ((double)a * (double)(sfpm)b) <= (double)FPM_INT_MAX);
113   assert((0 < a) == (0 < (sfpm)b) || ((double)a * (double)(sfpm)b) >= (double)FPM_INT_MIN);
114   r = (fpm)fpmimul_def(a, (sfpm)b);
115   return r;
116 }
117
118 fpm fpmmuli(fpm a, int b)
119 {
120   fpm r;
121   assert((0 < (sfpm)a) != (0 < b) || ((double)(sfpm)a * (double)b) <= (double)FPM_INT_MAX);
122   assert((0 < (sfpm)a) == (0 < b) || ((double)(sfpm)a * (double)b) >= (double)FPM_INT_MIN);
123   r = (fpm)fpmmuli_def((sfpm)a, b);
124   return r;
125 }
126
127 fpm fpmidiv(fpm a, int b)
128 {
129   fpm r;
130   r = (fpm)fpmidiv_def((sfpm)a, b);
131   return r;
132 }
133
134 #if 0
135 fpm fpmlmul(fpm a, fpm b)
136 {
137   fpm r;
138   assert((0 < (sfpm)a) != (0 < (sfpm)b) || ((double)(sfpm)a * (double)(sfpm)b / FPM_NUM) <= (double)FPM_INT_MAX);
139   assert((0 < (sfpm)a) == (0 < (sfpm)b) || ((double)(sfpm)a * (double)(sfpm)b / FPM_NUM) >= (double)FPM_INT_MIN);
140   r = (fpm)fpmlmul_def((sfpm)a, (sfpm)b);
141   return r;
142 }
143
144 fpm fpmldiv(fpm a, fpm b) {
145   fpm r;
146   r = (fpm)fpmldiv_def((sfpm)a, (sfpm)b);
147   return r;
148 }
149 #endif
150
151 #endif /* !defined(NDEBUG) && defined(USE_FPM) */
152
153 const char *olsr_etx_to_string(
154 #ifdef USE_FPM
155 fpm etx
156 #else
157 float etx
158 #endif
159 )
160 {
161   static int idx = 0;
162   static char ret[4][20];
163
164   if (etx >= INFINITE_ETX) {
165     return "INF";
166   }
167   idx = (idx + 1) % (sizeof(ret) / sizeof(ret[0]));
168 #ifdef USE_FPM
169   snprintf(ret[idx], sizeof(ret[0]), "%lld.%lld", (long long)((sfpm)etx >> FPM_BIT),
170            (long long)(100 * (ufpm) ((sfpm)(etx) & FPM_MSK) >> FPM_BIT));
171 #else
172   snprintf(ret[idx], sizeof(ret[0]), "%.3f", etx);
173 #endif
174   return ret[idx];
175 }
176
177 /*
178  * Local Variables:
179  * c-basic-offset: 2
180  * End:
181  */