chiark / gitweb /
5b5b625c777a197e79c10bf89b3143c2b42ff7d9
[mLib] / struct / buf-float.c
1 /* -*-c-*-
2  *
3  * Encoding and decoding floating-point values
4  *
5  * (c) 2023 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of the mLib utilities library.
11  *
12  * mLib is free software: you can redistribute it and/or modify it under
13  * the terms of the GNU Library General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or (at
15  * your option) any later version.
16  *
17  * mLib is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
20  * License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with mLib.  If not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25  * USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <float.h>
31 #include <math.h>
32
33 #include "bits.h"
34 #include "buf.h"
35 #include "fltfmt.h"
36
37 /*----- External functions ------------------------------------------------*/
38
39 /* --- @buf_getf{32,64}{,l,b} --- *
40  *
41  * Arguments:   @buf *b@ = a buffer to read from
42  *              @float *x_out@, @double *x_out@ = where to put the result
43  *
44  * Returns:     Zero on success, %$-1$% on failure (and the buffer is
45  *              broken).
46  *
47  * Use:         Get an IEEE Binary32 or Binary64 value from the buffer.
48  *              Conversion is performed using the `fltfmt' machinery, with
49  *              the usual round-to-nearest/ties-to-even rounding mode.
50  */
51
52 int buf_getf32(buf *b, float *x_out)
53 {
54   const octet *p;
55
56   p = buf_get(b, 4); if (!p) return (-1);
57   fltfmt_f32btoflt(x_out, p, FLTRND_NEAREVEN); return (0);
58 }
59
60 int buf_getf32l(buf *b, float *x_out)
61 {
62   const octet *p;
63
64   p = buf_get(b, 4); if (!p) return (-1);
65   fltfmt_f32ltoflt(x_out, p, FLTRND_NEAREVEN); return (0);
66 }
67
68 int buf_getf32b(buf *b, float *x_out)
69 {
70   const octet *p;
71
72   p = buf_get(b, 4); if (!p) return (-1);
73   fltfmt_f32ltoflt(x_out, p, FLTRND_NEAREVEN); return (0);
74 }
75
76 int (dbuf_getf32)(dbuf *db, float *x_out)
77   { return (dbuf_getf32(db, x_out)); }
78 int (dbuf_getf32l)(dbuf *db, float *x_out)
79   { return (dbuf_getf32l(db, x_out)); }
80 int (dbuf_getf32b)(dbuf *db, float *x_out)
81   { return (dbuf_getf32b(db, x_out)); }
82
83 int buf_getf64(buf *b, double *x_out)
84 {
85   const octet *p;
86
87   p = buf_get(b, 8); if (!p) return (-1);
88   fltfmt_f64btodbl(x_out, p, FLTRND_NEAREVEN); return (0);
89 }
90
91 int buf_getf64l(buf *b, double *x_out)
92 {
93   const octet *p;
94
95   p = buf_get(b, 8); if (!p) return (-1);
96   fltfmt_f64ltodbl(x_out, p, FLTRND_NEAREVEN); return (0);
97 }
98
99 int buf_getf64b(buf *b, double *x_out)
100 {
101   const octet *p;
102
103   p = buf_get(b, 8); if (!p) return (-1);
104   fltfmt_f64ltodbl(x_out, p, FLTRND_NEAREVEN); return (0);
105 }
106
107 int (dbuf_getf64)(dbuf *db, double *x_out)
108   { return (dbuf_getf64(db, x_out)); }
109 int (dbuf_getf64l)(dbuf *db, double *x_out)
110   { return (dbuf_getf64l(db, x_out)); }
111 int (dbuf_getf64b)(dbuf *db, double *x_out)
112   { return (dbuf_getf64b(db, x_out)); }
113
114 /* --- @buf_putf{32,64}{,l,b} --- *
115  *
116  * Arguments:   @buf *b@ = a buffer to write to
117  *              @double x@ = a number to write
118  *
119  * Returns:     Zero on success, %$-1$% on failure (and the buffer is
120  *              broken).
121  *
122  * Use:         Get an IEEE Binary32 or Binary64 value from the buffer.
123  *              Conversion is performed using the `fltfmt' machinery, with
124  *              the usual round-to-nearest/ties-to-even rounding mode.
125  */
126
127 int buf_putf32(buf *b, float x)
128 {
129   octet *p;
130
131   p = buf_get(b, 4); if (!p) return (-1);
132   fltfmt_flttof32b(p, x, FLTRND_NEAREVEN); return (0);
133 }
134
135 int buf_putf32l(buf *b, float x)
136 {
137   octet *p;
138
139   p = buf_get(b, 4); if (!p) return (-1);
140   fltfmt_flttof32l(p, x, FLTRND_NEAREVEN); return (0);
141 }
142
143 int buf_putf32b(buf *b, float x)
144 {
145   octet *p;
146
147   p = buf_get(b, 4); if (!p) return (-1);
148   fltfmt_flttof32b(p, x, FLTRND_NEAREVEN); return (0);
149 }
150
151 int (dbuf_putf32)(dbuf *db, float x)
152   { return (dbuf_putf32(db, x)); }
153 int (dbuf_putf32l)(dbuf *db, float x)
154   { return (dbuf_putf32l(db, x)); }
155 int (dbuf_putf32b)(dbuf *db, float x)
156   { return (dbuf_putf32b(db, x)); }
157
158 int buf_putf64(buf *b, double x)
159 {
160   octet *p;
161
162   p = buf_get(b, 8); if (!p) return (-1);
163   fltfmt_dbltof64b(p, x, FLTRND_NEAREVEN); return (0);
164 }
165
166 int buf_putf64l(buf *b, double x)
167 {
168   octet *p;
169
170   p = buf_get(b, 8); if (!p) return (-1);
171   fltfmt_dbltof64l(p, x, FLTRND_NEAREVEN); return (0);
172 }
173
174 int buf_putf64b(buf *b, double x)
175 {
176   octet *p;
177
178   p = buf_get(b, 8); if (!p) return (-1);
179   fltfmt_dbltof64b(p, x, FLTRND_NEAREVEN); return (0);
180 }
181
182 int (dbuf_putf64)(dbuf *db, double x)
183   { return (dbuf_putf64(db, x)); }
184 int (dbuf_putf64l)(dbuf *db, double x)
185   { return (dbuf_putf64l(db, x)); }
186 int (dbuf_putf64b)(dbuf *db, double x)
187   { return (dbuf_putf64b(db, x)); }
188
189 /*----- That's all, folks -------------------------------------------------*/