scanfloat_test.c revision 124707
1/*- 2 * Copyright (C) 2003 David Schultz <das@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * Test for scanf() floating point formats. 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD: head/tools/regression/lib/libc/stdio/test-scanfloat.c 124707 2004-01-19 05:30:56Z das $"); 33 34#include <assert.h> 35#include <float.h> 36#include <ieeefp.h> 37#include <locale.h> 38#include <math.h> 39#include <stdio.h> 40#include <string.h> 41 42#define eq(type, a, b) _eq(type##_EPSILON, (a), (b)) 43static int _eq(long double epsilon, long double a, long double b); 44 45extern int __scanfdebug; 46 47int 48main(int argc, char *argv[]) 49{ 50 char buf[128]; 51 long double ld = 0.0; 52 double d = 0.0; 53 float f = 0.0; 54 55 buf[0] = '\0'; 56 assert(setlocale(LC_NUMERIC, "")); 57 58 __scanfdebug = 1; 59 60 sscanf("3.141592", "%e", &f); 61 assert(eq(FLT, f, 3.141592)); 62 63 sscanf("3.141592653589793", "%lf", &d); 64 assert(eq(DBL, d, 3.141592653589793)); 65 66 sscanf("1.234568e+06", "%E", &f); 67 assert(eq(FLT, f, 1.234568e+06)); 68 69 sscanf("-1.234568e6", "%lF", &d); 70 assert(eq(DBL, d, -1.234568e6)); 71 72 sscanf("+1.234568e-52", "%LG", &ld); 73 assert(eq(LDBL, ld, 1.234568e-52L)); 74 75 sscanf("0.1", "%la", &d); 76 assert(eq(DBL, d, 0.1)); 77 78 sscanf("00.2", "%lA", &d); 79 assert(eq(DBL, d, 0.2)); 80 81 sscanf("123456", "%5le%s", &d, buf); 82 assert(eq(DBL, d, 12345.)); 83 assert(strcmp(buf, "6") == 0); 84 85 sscanf("1.0Q", "%*5le%s", buf); 86 assert(strcmp(buf, "Q") == 0); 87 88 sscanf("-1.23e", "%e%s", &f, buf); 89 assert(eq(FLT, f, -1.23)); 90 assert(strcmp(buf, "e") == 0); 91 92 sscanf("1.25e+", "%le%s", &d, buf); 93 assert(eq(DBL, d, 1.25)); 94 assert(strcmp(buf, "e+") == 0); 95 96 sscanf("1.23E4E5", "%le%s", &d, buf); 97 assert(eq(DBL, d, 1.23e4)); 98 assert(strcmp(buf, "E5") == 0); 99 100 sscanf("12e6", "%le", &d); 101 assert(eq(DBL, d, 12e6)); 102 103 sscanf("1.a", "%le%s", &d, buf); 104 assert(eq(DBL, d, 1.0)); 105 assert(strcmp(buf, "a") == 0); 106 107 sscanf(".0p4", "%le%s", &d, buf); 108 assert(eq(DBL, d, 0.0)); 109 assert(strcmp(buf, "p4") == 0); 110 111 d = 0.25; 112 assert(sscanf(".", "%le", &d) == 0); 113 assert(d == 0.25); 114 115 sscanf("0x08", "%le", &d); 116 assert(d == 0x8p0); 117 118 sscanf("0x90a.bcdefP+09a", "%le%s", &d, buf); 119 assert(d == 0x90a.bcdefp+09); 120 assert(strcmp(buf, "a") == 0); 121 122#if (LDBL_MANT_DIG > DBL_MANT_DIG) && !defined(__i386__) 123 sscanf("3.14159265358979323846", "%Lg", &ld); 124 assert(eq(LDBL, ld, 3.14159265358979323846L)); 125 126 sscanf(" 0X.0123456789abcdefffp-3g", "%Le%s", &ld, buf); 127 assert(ld == 0x0.0123456789abcdefffp-3L); 128 assert(strcmp(buf, "g") == 0); 129#endif 130 131 sscanf("0xg", "%le%s", &d, buf); 132 assert(d == 0.0); 133 assert(strcmp(buf, "xg") == 0); 134 135 assert(setlocale(LC_NUMERIC, "ru_RU.ISO8859-5")); /* decimalpoint==, */ 136 137 sscanf("1.23", "%le%s", &d, buf); 138 assert(d == 1.0); 139 assert(strcmp(buf, ".23") == 0); 140 141 sscanf("1,23", "%le", &d); 142 assert(d == 1.23); 143 144 assert(setlocale(LC_NUMERIC, "")); 145 146 sscanf("-Inf", "%le", &d); 147 assert(d < 0.0 && isinf(d)); 148 149 sscanf("iNfInItY and beyond", "%le%s", &d, buf); 150 assert(d > 0.0 && isinf(d)); 151 assert(strcmp(buf, " and beyond")); 152 153 sscanf("NaN", "%le", &d); 154 assert(isnan(d)); 155 156 sscanf("NAN(123Y", "%le%s", &d, buf); 157 assert(isnan(d)); 158 assert(strcmp(buf, "(123Y") == 0); 159 160 sscanf("nan(f00f)plugh", "%le%s", &d, buf); 161 assert(isnan(d)); 162 assert(strcmp(buf, "plugh") == 0); 163 164 sscanf("-nan", "%le", &d); 165 assert(isnan(d)); 166 167 fpsetround(FP_RN); 168 169 /* strtod() should round small numbers to 0. */ 170 sscanf("0x1.23p-5000", "%le", &d); 171 assert(d == 0.0); 172 173 /* Extra digits in a denormal shouldn't break anything. */ 174 sscanf("0x1.2345678p-1050", "%le", &d); 175 assert(d == 0x1.234568p-1050); 176 177 printf("PASS scanfloat\n"); 178 179 return (0); 180} 181 182static int 183_eq(long double epsilon, long double a, long double b) 184{ 185 long double delta; 186 187 delta = a - b; 188 if (delta < 0) /* XXX no fabsl() */ 189 delta = -delta; 190 return (delta <= epsilon); 191} 192