Back to index

glibc  2.9
tst-efgcvt.c
Go to the documentation of this file.
00001 /* Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #ifndef _GNU_SOURCE
00020 # define _GNU_SOURCE 1
00021 #endif
00022 
00023 #include <float.h>
00024 #include <math.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 
00029 int error_count;
00030 
00031 typedef struct
00032 {
00033   double value;
00034   int ndigit;
00035   int decpt;
00036   char result[30];
00037 } testcase;
00038 
00039 typedef char * ((*efcvt_func) (double, int, int *, int *));
00040 
00041 typedef int ((*efcvt_r_func) (double, int, int *, int *, char *, size_t));
00042 
00043 
00044 static testcase ecvt_tests[] =
00045 {
00046   { 0.0, 0, 1, "" },
00047   { 10.0, 0, 2, "" },
00048   { 10.0, 1, 2, "1" },
00049   { 10.0, 5, 2, "10000" },
00050   { -12.0, 5, 2, "12000" },
00051   { 0.2, 4, 0, "2000" },
00052   { 0.02, 4, -1, "2000" },
00053   { 5.5, 1, 1, "6" },
00054   { 1.0, -1, 1, "" },
00055   { 0.01, 2, -1, "10" },
00056   { 100.0, -2, 3, "" },
00057   { 100.0, -5, 3, "" },
00058   { 100.0, -4, 3, "" },
00059   { 100.01, -4, 3, "" },
00060   { 123.01, -4, 3, "" },
00061   { 126.71, -4, 3, "" },
00062   { 0.0, 4, 1, "0000" },
00063 #if DBL_MANT_DIG == 53
00064   { 0x1p-1074, 3, -323, "494" },
00065   { -0x1p-1074, 3, -323, "494" },
00066 #endif
00067   /* -1.0 is end marker.  */
00068   { -1.0, 0, 0, "" }
00069 };
00070 
00071 static testcase fcvt_tests[] =
00072 {
00073   { 0.0, 0, 1, "0" },
00074   { 10.0, 0, 2, "10" },
00075   { 10.0, 1, 2, "100" },
00076   { 10.0, 4, 2, "100000" },
00077   { -12.0, 5, 2, "1200000" },
00078   { 0.2, 4, 0, "2000" },
00079   { 0.02, 4, -1, "200" },
00080   { 5.5, 1, 1, "55" },
00081   { 5.5, 0, 1, "6" },
00082   { 0.01, 2, -1, "1" },
00083   { 100.0, -2, 3, "100" },
00084   { 100.0, -5, 3, "100" },
00085   { 100.0, -4, 3, "100" },
00086   { 100.01, -4, 3, "100" },
00087   { 123.01, -4, 3, "100" },
00088   { 126.71, -4, 3, "100" },
00089   { 322.5, 16, 3, "3225000000000000000" },
00090   /* -1.0 is end marker.  */
00091   { -1.0, 0, 0, "" }
00092 };
00093 
00094 static void
00095 output_error (const char *name, double value, int ndigit,
00096              const char *exp_p, int exp_decpt, int exp_sign,
00097              char *res_p, int res_decpt, int res_sign)
00098 {
00099   printf ("%s returned wrong result for value: %f, ndigits: %d\n",
00100          name, value, ndigit);
00101   printf ("Result was p: \"%s\", decpt: %d, sign: %d\n",
00102          res_p, res_decpt, res_sign);
00103   printf ("Should be  p: \"%s\", decpt: %d, sign: %d\n",
00104          exp_p, exp_decpt, exp_sign);
00105   ++error_count;
00106 }
00107 
00108 
00109 static void
00110 output_r_error (const char *name, double value, int ndigit,
00111               const char *exp_p, int exp_decpt, int exp_sign, int exp_return,
00112               char *res_p, int res_decpt, int res_sign, int res_return)
00113 {
00114   printf ("%s returned wrong result for value: %f, ndigits: %d\n",
00115          name, value, ndigit);
00116   printf ("Result was buf: \"%s\", decpt: %d, sign: %d return value: %d\n",
00117          res_p, res_decpt, res_sign, res_return);
00118   printf ("Should be  buf: \"%s\", decpt: %d, sign: %d\n",
00119          exp_p, exp_decpt, exp_sign);
00120   ++error_count;
00121 }
00122 
00123 static void
00124 test (testcase tests[], efcvt_func efcvt, const char *name)
00125 {
00126   int no = 0;
00127   int decpt, sign;
00128   char *p;
00129 
00130   while (tests[no].value != -1.0)
00131     {
00132       p = efcvt (tests[no].value, tests[no].ndigit, &decpt, &sign);
00133       if (decpt != tests[no].decpt
00134          || sign != (tests[no].value < 0)
00135          || strcmp (p, tests[no].result) != 0)
00136        output_error (name, tests[no].value, tests[no].ndigit,
00137                     tests[no].result, tests[no].decpt,
00138                     (tests[no].value < 0),
00139                     p, decpt, sign);
00140       ++no;
00141     }
00142 }
00143 
00144 static void
00145 test_r (testcase tests[], efcvt_r_func efcvt_r, const char *name)
00146 {
00147   int no = 0;
00148   int decpt, sign, res;
00149   char buf [1024];
00150 
00151 
00152   while (tests[no].value != -1.0)
00153     {
00154       res = efcvt_r (tests[no].value, tests[no].ndigit, &decpt, &sign,
00155                    buf, sizeof (buf));
00156       if (res != 0
00157          || decpt != tests[no].decpt
00158          || sign != (tests[no].value < 0)
00159          || strcmp (buf, tests[no].result) != 0)
00160        output_r_error (name, tests[no].value, tests[no].ndigit,
00161                      tests[no].result, tests[no].decpt, 0,
00162                      (tests[no].value < 0),
00163                      buf, decpt, sign, res);
00164       ++no;
00165     }
00166 }
00167 
00168 static void
00169 special (void)
00170 {
00171   int decpt, sign, res;
00172   char *p;
00173   char buf [1024];
00174 
00175   p = ecvt (NAN, 10, &decpt, &sign);
00176   if (sign != 0 || strcmp (p, "nan") != 0)
00177     output_error ("ecvt", NAN, 10, "nan", 0, 0, p, decpt, sign);
00178 
00179   p = ecvt (INFINITY, 10, &decpt, &sign);
00180   if (sign != 0 || strcmp (p, "inf") != 0)
00181     output_error ("ecvt", NAN, 10, "inf", 0, 0, p, decpt, sign);
00182 
00183   /* Simply make sure these calls with large NDIGITs don't crash.  */
00184   (void) ecvt (123.456, 10000, &decpt, &sign);
00185   (void) fcvt (123.456, 10000, &decpt, &sign);
00186 
00187   /* Some tests for for the reentrant functions.  */
00188   /* Use a too small buffer.  */
00189   res = ecvt_r (123.456, 10, &decpt, &sign, buf, 1);
00190   if (res == 0)
00191     {
00192       printf ("ecvt_r with a too small buffer was succesful.\n");
00193       ++error_count;
00194     }
00195   res = fcvt_r (123.456, 10, &decpt, &sign, buf, 1);
00196   if (res == 0)
00197     {
00198       printf ("fcvt_r with a too small buffer was succesful.\n");
00199       ++error_count;
00200     }
00201 }
00202 
00203 
00204 int
00205 main (void)
00206 {
00207   test (ecvt_tests, ecvt, "ecvt");
00208   test (fcvt_tests, fcvt, "fcvt");
00209   test_r (ecvt_tests, ecvt_r, "ecvt_r");
00210   test_r (fcvt_tests, fcvt_r, "fcvt_r");
00211   special ();
00212 
00213   return error_count;
00214 }