OSDN Git Service

2011-01-31 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / libquadmath / quadmath_io.c
1 /* GCC Quad-Precision Math Library
2    Copyright (C) 2010, 2011 Free Software Foundation, Inc.
3    Written by Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
4
5 This file is part of the libquadmath library.
6 Libquadmath 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.
10
11 Libquadmath 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.
15
16 You should have received a copy of the GNU Library General Public
17 License along with libquadmath; 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.  */
20
21 #include "quadmath.h"
22 #include <stdio.h>
23 #include <string.h>
24
25 #define ABS(x) ((x) >= 0 ? (x) : -(x))
26
27
28
29 static void
30 format (char * res, const __float128 x, size_t n)
31 {
32   char buffer[1024];
33   char *p;
34
35   memset (buffer, 0, sizeof(buffer));
36
37   g_Qfmt (buffer, &x, n + 1, sizeof(buffer) - 3);
38   p = buffer + (*buffer == '-' ? 1 : 0);
39
40   /* The sign is the easiest part.  */
41   res[0] = (signbitq (x) ? '-' : '+');
42
43   if (*p == '.')
44   {
45     /* We have a number smaller than 1, without exponent.  */
46     int exp = 0;
47     char *c;
48
49     for (c = p+1; *c == '0'; c++)
50       exp++;
51
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);
57
58     res[1] = res[2];
59     res[2] = '.';
60
61     return;
62   }
63
64   /* Now, do we already have an exponent.  */
65   char *c;
66   for (c = p; *c && *c != 'e'; c++)
67     ;
68   if (*c)
69   {
70     int exp = strtol (c + 1, NULL, 10);
71
72     size_t l = c - p;
73
74     memcpy (res + 1, p, l);
75     if (l <= n + 1)
76       memset (res + 1 + l, '0', (int) n - l + 2);
77
78     sprintf (res + n + 3, "e%c%02d", exp >= 0 ? '+' : '-', ABS(exp));
79
80     return;
81   }
82   else
83   {
84     /* If we have no exponent, normalize and add the exponent.  */
85     for (c = p; *c && *c != '.'; c++)
86       ;
87
88     res[1] = *p;
89     res[2] = '.';
90
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);
97
98     return;
99   }
100 }
101
102
103 void
104 quadmath_flt128tostr (char *s, size_t size, size_t n, __float128 x)
105 {
106   char buffer[1024];
107   memset (buffer, 0, sizeof(buffer));
108   format (buffer, x, n);
109   memcpy (s, buffer, size);
110 }