openat: don’t close (-1)
[gnulib.git] / lib / getpayloadf.c
blob6e24c5540757361cd84be9520e0a9d039d6a607d
1 /* Extract the payload of a NaN 'float'.
2 Copyright 2024 Free Software Foundation, Inc.
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation, either version 3 of the
7 License, or (at your option) any later version.
9 This file is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible. */
19 #include <config.h>
21 /* Specification. */
22 #include <math.h>
24 #include <float.h>
25 #include <stdint.h>
26 #include <string.h>
28 float
29 getpayloadf (const float *value)
31 if (isnanf (*value))
33 #if FLT_MANT_DIG == 24
34 union { uint32_t i; float f; } x;
35 # if 0
36 x.f = *value;
37 # else
38 /* On 32-bit x86 processors, as well as on x86_64 processors with
39 CC="gcc -mfpmath=387", the evaluation of *value above is done
40 through an 'flds' instruction, which converts a signalling NaN to
41 a quiet NaN. See
42 <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
43 for details. Use memcpy to avoid this. */
44 memcpy (&x.f, value, sizeof (float));
45 # endif
46 int32_t payload = x.i & (((uint32_t) 1 << (FLT_MANT_DIG - 2)) - 1);
47 return payload;
48 #else
49 # error "Please port gnulib getpayloadf.c to your platform!"
50 #endif
52 else
53 return -1.0f;