@@@ mostly bench docs
[mLib] / struct / buf-float.c
CommitLineData
e63124bc
MW
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"
b1a20bee 35#include "fltfmt.h"
289651a7 36#include "macros.h"
e63124bc 37
289651a7
MW
38/*----- Constants ---------------------------------------------------------*/
39
40/* Tolerable errors. These aren't great, and all of them imply a failure to
41 * faithfully pass the value on, but they're also the inevitable consequence
42 * of having different floating-point systems.
43 */
44#define IGNERR (FLTERR_INEXACT | FLTERR_OFLOW | FLTERR_UFLOW)
45
46/*----- Main code ---------------------------------------------------------*/
47
48#define FORMATS(_) \
49 _(flt, float, f32, 4) \
50 _(dbl, double, f64, 8)
e63124bc 51
b1a20bee 52/* --- @buf_getf{32,64}{,l,b} --- *
31d0247c 53 *
b1a20bee
MW
54 * Arguments: @buf *b@ = a buffer to read from
55 * @float *x_out@, @double *x_out@ = where to put the result
31d0247c 56 *
b1a20bee
MW
57 * Returns: Zero on success, %$-1$% on failure (and the buffer is
58 * broken).
31d0247c 59 *
b1a20bee
MW
60 * Use: Get an IEEE Binary32 or Binary64 value from the buffer.
61 * Conversion is performed using the `fltfmt' machinery, with
62 * the usual round-to-nearest/ties-to-even rounding mode.
31d0247c
MW
63 */
64
289651a7
MW
65#define DEFGET1(ty, cty, fty, e, xe, w) \
66 int GLUE3(buf_get, fty, xe)(buf *b, cty *x_out) \
67 { \
68 const octet *p; \
69 unsigned err; \
70 \
71 p = buf_get(b, w); if (!p) return (-1); \
72 err = fltfmt_##fty##e##to##ty(x_out, p, FLTRND_NEAREVEN); \
73 if (err&~IGNERR) { BBREAK(b); return (-1); } \
74 return (0); \
75 } \
76 int (GLUE3(dbuf_get, fty, xe))(dbuf *db, cty *x_out) \
77 { return (GLUE3(dbuf_get, fty, xe)(db, x_out)); }
78
79#define DEFGET(ty, cty, fty, w) \
80 DEFGET1(ty, cty, fty, b, EMPTY, w) \
81 DEFGET1(ty, cty, fty, l, l, w) \
82 DEFGET1(ty, cty, fty, b, b, w)
83
84FORMATS(DEFGET)
85
86#undef DEFGET1
87#undef DEFGET
31d0247c 88
b1a20bee 89/* --- @buf_putf{32,64}{,l,b} --- *
31d0247c
MW
90 *
91 * Arguments: @buf *b@ = a buffer to write to
92 * @double x@ = a number to write
93 *
b1a20bee
MW
94 * Returns: Zero on success, %$-1$% on failure (and the buffer is
95 * broken).
31d0247c 96 *
b1a20bee
MW
97 * Use: Get an IEEE Binary32 or Binary64 value from the buffer.
98 * Conversion is performed using the `fltfmt' machinery, with
99 * the usual round-to-nearest/ties-to-even rounding mode.
31d0247c
MW
100 */
101
289651a7
MW
102#define DEFPUT1(ty, cty, fty, e, xe, w) \
103 int GLUE3(buf_put, fty, xe)(buf *b, cty x) \
104 { \
105 octet *p; \
106 unsigned err; \
107 \
108 p = buf_get(b, w); if (!p) return (-1); \
109 err = fltfmt_##ty##to##fty##e(p, x, FLTRND_NEAREVEN); \
110 if (err&~IGNERR) { BBREAK(b); return (-1); } \
111 return (0); \
112 } \
113 int (GLUE3(dbuf_put, fty, xe))(dbuf *db, cty x) \
114 { return (GLUE3(dbuf_put, fty, xe)(db, x)); }
115
116#define DEFPUT(ty, cty, fty, w) \
117 DEFPUT1(ty, cty, fty, b, EMPTY, w) \
118 DEFPUT1(ty, cty, fty, l, l, w) \
119 DEFPUT1(ty, cty, fty, b, b, w)
120
121FORMATS(DEFPUT)
122
123#undef DEFPUT1
124#undef DEFPUT
31d0247c 125
e63124bc 126/*----- That's all, folks -------------------------------------------------*/