1 /* Processed by ecpg (regression mode) */ 2 /* These include files are added by the preprocessor */ 3 #include <ecpglib.h> 4 #include <ecpgerrno.h> 5 #include <sqlca.h> 6 /* End of automatic include section */ 7 #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y)) 8 9 #line 1 "num_test2.pgc" 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <pgtypes_numeric.h> 13 #include <pgtypes_error.h> 14 #include <decimal.h> 15 16 17 #line 1 "regression.h" 18 19 20 21 22 23 24 #line 7 "num_test2.pgc" 25 26 27 28 #line 1 "printf_hack.h" 29 /* 30 * print_double(x) has the same effect as printf("%g", x), but is intended 31 * to produce the same formatting across all platforms. 32 */ 33 static void 34 print_double(double x) 35 { 36 #ifdef WIN32 37 /* Change Windows' 3-digit exponents to look like everyone else's */ 38 char convert[128]; 39 int vallen; 40 41 sprintf(convert, "%g", x); 42 vallen = strlen(convert); 43 44 if (vallen >= 6 && 45 convert[vallen - 5] == 'e' && 46 convert[vallen - 3] == '0') 47 { 48 convert[vallen - 3] = convert[vallen - 2]; 49 convert[vallen - 2] = convert[vallen - 1]; 50 convert[vallen - 1] = '\0'; 51 } 52 53 printf("%s", convert); 54 #else 55 printf("%g", x); 56 #endif 57 } 58 59 #line 9 "num_test2.pgc" 60 61 62 63 char* nums[] = { "2E394", "-2", ".794", "3.44", "592.49E21", "-32.84e4", 64 "2E-394", ".1E-2", "+.0", "-592.49E-07", "+32.84e-4", 65 ".500001", "-.5000001", 66 "1234567890123456789012345678.91", /* 30 digits should fit 67 into decimal */ 68 "1234567890123456789012345678.921", /* 31 digits should NOT 69 fit into decimal */ 70 "not a number", 71 NULL}; 72 73 74 static void 75 check_errno(void); 76 77 int 78 main(void) 79 { 80 char *text="error\n"; 81 char *endptr; 82 numeric *num, *nin; 83 decimal *dec; 84 long l; 85 int i, j, k, q, r, count = 0; 86 double d; 87 numeric **numarr = (numeric **) calloc(1, sizeof(numeric)); 88 89 ECPGdebug(1, stderr); 90 91 for (i = 0; nums[i]; i++) 92 { 93 num = PGTYPESnumeric_from_asc(nums[i], &endptr); 94 if (!num) check_errno(); 95 if (endptr != NULL) 96 { 97 printf("endptr of %d is not NULL\n", i); 98 if (*endptr != '\0') 99 printf("*endptr of %d is not \\0\n", i); 100 } 101 if (!num) continue; 102 103 numarr = realloc(numarr, sizeof(numeric *) * (count + 1)); 104 numarr[count++] = num; 105 106 text = PGTYPESnumeric_to_asc(num, -1); 107 if (!text) check_errno(); 108 printf("num[%d,1]: %s\n", i, text); PGTYPESchar_free(text); 109 text = PGTYPESnumeric_to_asc(num, 0); 110 if (!text) check_errno(); 111 printf("num[%d,2]: %s\n", i, text); PGTYPESchar_free(text); 112 text = PGTYPESnumeric_to_asc(num, 1); 113 if (!text) check_errno(); 114 printf("num[%d,3]: %s\n", i, text); PGTYPESchar_free(text); 115 text = PGTYPESnumeric_to_asc(num, 2); 116 if (!text) check_errno(); 117 printf("num[%d,4]: %s\n", i, text); PGTYPESchar_free(text); 118 119 nin = PGTYPESnumeric_new(); 120 text = PGTYPESnumeric_to_asc(nin, 2); 121 if (!text) check_errno(); 122 printf("num[%d,5]: %s\n", i, text); PGTYPESchar_free(text); 123 124 r = PGTYPESnumeric_to_long(num, &l); 125 if (r) check_errno(); 126 printf("num[%d,6]: %ld (r: %d)\n", i, r?0L:l, r); 127 if (r == 0) 128 { 129 r = PGTYPESnumeric_from_long(l, nin); 130 if (r) check_errno(); 131 text = PGTYPESnumeric_to_asc(nin, 2); 132 q = PGTYPESnumeric_cmp(num, nin); 133 printf("num[%d,7]: %s (r: %d - cmp: %d)\n", i, text, r, q); 134 PGTYPESchar_free(text); 135 } 136 137 r = PGTYPESnumeric_to_int(num, &k); 138 if (r) check_errno(); 139 printf("num[%d,8]: %d (r: %d)\n", i, r?0:k, r); 140 if (r == 0) 141 { 142 r = PGTYPESnumeric_from_int(k, nin); 143 if (r) check_errno(); 144 text = PGTYPESnumeric_to_asc(nin, 2); 145 q = PGTYPESnumeric_cmp(num, nin); 146 printf("num[%d,9]: %s (r: %d - cmp: %d)\n", i, text, r, q); 147 PGTYPESchar_free(text); 148 } 149 150 if (i != 6) 151 { 152 /* underflow does not work reliable on several archs, so not testing it here */ 153 /* this is a libc problem since we only call strtod() */ 154 155 r = PGTYPESnumeric_to_double(num, &d); 156 if (r) check_errno(); 157 printf("num[%d,10]: ", i); 158 print_double(r ? 0.0 : d); 159 printf(" (r: %d)\n", r); 160 } 161 162 /* do not test double to numeric because 163 * - extra digits are different on different architectures 164 * - PGTYPESnumeric_from_double internally calls PGTYPESnumeric_from_asc anyway 165 */ 166 167 dec = PGTYPESdecimal_new(); 168 r = PGTYPESnumeric_to_decimal(num, dec); 169 if (r) check_errno(); 170 /* we have no special routine for outputting decimal, it would 171 * convert to a numeric anyway */ 172 printf("num[%d,11]: - (r: %d)\n", i, r); 173 if (r == 0) 174 { 175 r = PGTYPESnumeric_from_decimal(dec, nin); 176 if (r) check_errno(); 177 text = PGTYPESnumeric_to_asc(nin, 2); 178 q = PGTYPESnumeric_cmp(num, nin); 179 printf("num[%d,12]: %s (r: %d - cmp: %d)\n", i, text, r, q); 180 PGTYPESchar_free(text); 181 } 182 183 PGTYPESdecimal_free(dec); 184 PGTYPESnumeric_free(nin); 185 printf("\n"); 186 } 187 188 for (i = 0; i < count; i++) 189 { 190 for (j = 0; j < count; j++) 191 { 192 numeric* a = PGTYPESnumeric_new(); 193 numeric* s = PGTYPESnumeric_new(); 194 numeric* m = PGTYPESnumeric_new(); 195 numeric* d = PGTYPESnumeric_new(); 196 r = PGTYPESnumeric_add(numarr[i], numarr[j], a); 197 if (r) 198 { 199 check_errno(); 200 printf("r: %d\n", r); 201 } 202 else 203 { 204 text = PGTYPESnumeric_to_asc(a, 10); 205 printf("num[a,%d,%d]: %s\n", i, j, text); 206 PGTYPESchar_free(text); 207 } 208 r = PGTYPESnumeric_sub(numarr[i], numarr[j], s); 209 if (r) 210 { 211 check_errno(); 212 printf("r: %d\n", r); 213 } 214 else 215 { 216 text = PGTYPESnumeric_to_asc(s, 10); 217 printf("num[s,%d,%d]: %s\n", i, j, text); 218 PGTYPESchar_free(text); 219 } 220 r = PGTYPESnumeric_mul(numarr[i], numarr[j], m); 221 if (r) 222 { 223 check_errno(); 224 printf("r: %d\n", r); 225 } 226 else 227 { 228 text = PGTYPESnumeric_to_asc(m, 10); 229 printf("num[m,%d,%d]: %s\n", i, j, text); 230 PGTYPESchar_free(text); 231 } 232 r = PGTYPESnumeric_div(numarr[i], numarr[j], d); 233 if (r) 234 { 235 check_errno(); 236 printf("r: %d\n", r); 237 } 238 else 239 { 240 text = PGTYPESnumeric_to_asc(d, 10); 241 printf("num[d,%d,%d]: %s\n", i, j, text); 242 PGTYPESchar_free(text); 243 } 244 245 PGTYPESnumeric_free(a); 246 PGTYPESnumeric_free(s); 247 PGTYPESnumeric_free(m); 248 PGTYPESnumeric_free(d); 249 } 250 } 251 252 for (i = 0; i < count; i++) 253 { 254 text = PGTYPESnumeric_to_asc(numarr[i], -1); 255 printf("%d: %s\n", i, text); 256 PGTYPESchar_free(text); 257 PGTYPESnumeric_free(numarr[i]); 258 } 259 free(numarr); 260 261 return 0; 262 } 263 264 static void 265 check_errno(void) 266 { 267 switch(errno) 268 { 269 case 0: 270 printf("(no errno set) - "); 271 break; 272 case PGTYPES_NUM_OVERFLOW: 273 printf("(errno == PGTYPES_NUM_OVERFLOW) - "); 274 break; 275 case PGTYPES_NUM_UNDERFLOW: 276 printf("(errno == PGTYPES_NUM_UNDERFLOW) - "); 277 break; 278 case PGTYPES_NUM_BAD_NUMERIC: 279 printf("(errno == PGTYPES_NUM_BAD_NUMERIC) - "); 280 break; 281 case PGTYPES_NUM_DIVIDE_ZERO: 282 printf("(errno == PGTYPES_NUM_DIVIDE_ZERO) - "); 283 break; 284 default: 285 printf("(unknown errno (%d))\n", errno); 286 printf("(libc: (%s)) ", strerror(errno)); 287 break; 288 } 289 290 } 291