2011-01-13 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
[official-gcc.git] / libquadmath / quadmath_io.c
blob48a8fe75c584f965edcdfe0edd8599ccec8b415d
1 /* GCC Quad-Precision Math Library
2 Copyright (C) 2010 Free Software Foundation, Inc.
3 Written by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
5 This file is part of the libiberty library.
6 Libiberty is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 Libiberty is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with libiberty; see the file COPYING.LIB. If
18 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19 Boston, MA 02110-1301, USA. */
21 #include "quadmath.h"
22 #include <stdio.h>
23 #include <string.h>
25 #define ABS(x) ((x) >= 0 ? (x) : -(x))
29 static void
30 format (char * res, const __float128 x, size_t n)
32 char buffer[1024];
33 char *p;
35 memset (buffer, 0, sizeof(buffer));
37 g_Qfmt (buffer, &x, n + 1, sizeof(buffer) - 3);
38 p = buffer + (*buffer == '-' ? 1 : 0);
40 // The sign is the easiest part
41 res[0] = (signbitq (x) ? '-' : '+');
43 if (*p == '.')
45 // We have a number smaller than 1, without exponent
46 int exp = 0;
47 char *c;
49 for (c = p+1; *c == '0'; c++)
50 exp++;
52 // We move the string "exp" characters left
53 size_t l = strlen (p+1+exp);
54 memcpy (res + 2, p + 1 + exp, l);
55 memset (res + 2 + l, '0', n - l + 1);
56 sprintf (res + n + 3, "e-%02d", exp + 1);
58 res[1] = res[2];
59 res[2] = '.';
61 return;
64 // Now, do we already have an exponent
65 char *c;
66 for (c = p; *c && *c != 'e'; c++)
68 if (*c)
70 int exp = strtol (c + 1, NULL, 10);
72 size_t l = c - p;
74 memcpy (res + 1, p, l);
75 if (l <= n + 1)
76 memset (res + 1 + l, '0', (int) n - l + 2);
78 sprintf (res + n + 3, "e%c%02d", exp >= 0 ? '+' : '-', ABS(exp));
80 return;
82 else
84 // If we have no exponent, normalize and add the exponent
85 for (c = p; *c && *c != '.'; c++)
88 res[1] = *p;
89 res[2] = '.';
91 size_t l = c - p;
92 memcpy (res + 3, p + 1, l);
93 size_t l2 = strlen (c + 1);
94 memcpy (res + 2 + l, c + 1, l2);
95 memset (res + 2 + l + l2, '0', n - (l + l2) + 1);
96 sprintf (res + n + 3, "e+%02d", l - 1);
98 return;
103 void
104 quadmath_dtoaq (char *s, size_t size, size_t n, __float128 x)
106 char buffer[1024];
107 memset (buffer, 0, sizeof(buffer));
108 format (buffer, x, n);
109 memcpy (s, buffer, size);