static void special (void) { int decpt, sign, res; char *p; char buf [1024]; p = ecvt (NAN, 10, &decpt, &sign); if (sign != 0 || strcmp (p, "nan") != 0) output_error ("ecvt", NAN, 10, "nan", 0, 0, p, decpt, sign); p = ecvt (INFINITY, 10, &decpt, &sign); if (sign != 0 || strcmp (p, "inf") != 0) output_error ("ecvt", INFINITY, 10, "inf", 0, 0, p, decpt, sign); /* Simply make sure these calls with large NDIGITs don't crash. */ (void) ecvt (123.456, 10000, &decpt, &sign); (void) fcvt (123.456, 10000, &decpt, &sign); /* Some tests for the reentrant functions. */ /* Use a too small buffer. */ res = ecvt_r (123.456, 10, &decpt, &sign, buf, 1); if (res == 0) { printf ("ecvt_r with a too small buffer was succesful.\n"); ++error_count; } res = fcvt_r (123.456, 10, &decpt, &sign, buf, 1); if (res == 0) { printf ("fcvt_r with a too small buffer was succesful.\n"); ++error_count; } }
int main (int argc, char * argv[]) { double valeur; int nb_chiffres; int position; int signe; char * retour; if ((argc != 3) || (sscanf(argv[1], "%lf", & valeur) != 1) || (sscanf(argv[2], "%d", & nb_chiffres) != 1)) { fprintf(stderr, "Syntaxe : %s valeur nb_chiffres \n", argv[0]); exit (EXIT_FAILURE); } retour = ecvt(valeur, nb_chiffres, & position, & signe); fprintf(stdout, "ecvt() = %s \n", retour); fprintf(stdout, " position = %d \n", position); fprintf(stdout, " signe = %d \n", signe); retour = fcvt(valeur, nb_chiffres, & position, & signe); fprintf(stdout, "fcvt() = %s \n", retour); fprintf(stdout, " position = %d \n", position); fprintf(stdout, " signe = %d \n", signe); return EXIT_SUCCESS; }
/* * Transforma un double in string. */ void dtoa(double d, char s[5]) { char *str = (char*) malloc(5*sizeof(char)); int aux1, aux2; int aux = (int) d; if ((d - aux) > 0.96) aux++; itoa(aux, str, 10); s[0] = str[0]; s[1] = '.'; d = d - ((int) d); if ((d >= 0.96) || (d <= 0.04)) { s[2] = '0'; s[3] = '0'; s[4] = '\0'; } else if ((d > 0.04) && (d <= 0.09)) { s[2] = '0'; s[3] = '5'; s[4] = '\0'; } else { str = (char*) ecvt(d, 2, &aux1, &aux2); s[2] = str[0]; s[3] = str[1]; s[4] = '\0'; } free(s); }
hndop() { char *str; int sign,ndig,dec; float inte; if(temp[j][i+1]=='^') { if(temp[j][i+2]>='1'&&temp[j][i+2]<='9') { inte=atoi(&stack[0])*atoi(&temp[j][i+2]); str=ecvt(inte,2,&dec,&sign); ans[l++]=str[0]; ans[l++]=str[1]; ans[l++]=ch; ans[l++]='^'; printf("%d",atoi(&stack[0])*atoi(&temp[j][i+2])); ans[l++]=temp[j][i+2]-1; } } if(temp[j][i+1]=='\0') { ans[l++]=ch; } ans[l]=0; printf("\n%s",ans); }
int main(int argc, char ** argv) { int a, b; char * conv=ecvt(9e0,20,&a,&b); printf("ecvt Test: %f -> %s, %d, %d\n",9e0,conv,a,b); }
void main() { char *str; int dec, sign; str = ecvt( 123.456789, 6, &dec, &sign ); printf( "str=%s, dec=%d, sign=%d\n", str,dec,sign ); }
static char *gcvt(double number, int ndigit, char *buf, boolean_e altform) { int sign, decpt; register char *p1, *p2; register int i; char buf1[NDIG]; p1 = ecvt(number, ndigit, &decpt, &sign, buf1); p2 = buf; if (sign) *p2++ = '-'; for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--) ndigit--; if ((decpt >= 0 && decpt - ndigit > 4) || (decpt < 0 && decpt < -3)) { /* use E-style */ decpt--; *p2++ = *p1++; *p2++ = '.'; for (i = 1; i < ndigit; i++) *p2++ = *p1++; *p2++ = 'e'; if (decpt < 0) { decpt = -decpt; *p2++ = '-'; } else *p2++ = '+'; if (decpt / 100 > 0) *p2++ = decpt / 100 + '0'; if (decpt / 10 > 0) *p2++ = (decpt % 100) / 10 + '0'; *p2++ = decpt % 10 + '0'; } else { if (decpt <= 0) { if (*p1 != '0') *p2++ = '.'; while (decpt < 0) { decpt++; *p2++ = '0'; } } for (i = 1; i <= ndigit; i++) { *p2++ = *p1++; if (i == decpt) *p2++ = '.'; } if (ndigit < decpt) { while (ndigit++ < decpt) *p2++ = '0'; *p2++ = '.'; } } if (p2[-1] == '.' && !altform) p2--; *p2 = '\0'; return (buf); }
void FloatToString(FloatType f, Char* sz) { Char* buffer = sz + 1; static const int digitCount = 6; int decimal, sign; // ecvt rounds the string for us: http://www.datafocus.com/docs/man3/ecvt.3.asp char* end = ecvt(f, digitCount, &decimal, &sign); if (sign != 0) (*buffer++) = '-'; int count = digitCount; if (decimal > digitCount) { // We use the scientific notation: P.MeX (*buffer++) = (*end++); // P is one character. (*buffer++) = '.'; // Mantissa (cleaned for zeroes) for (--count; count > 0; --count) if (end[count - 1] != '0') break; for (int i = 0; i < count; ++i) (*buffer++) = (*end++); if (buffer[-1] == '.') --buffer; // Exponent (*buffer++) = 'e'; uint32 exponent = decimal - 1; // X if (exponent >= 10) (*buffer++) = (Char) ('0' + (exponent / 10)); (*buffer++) = (Char) ('0' + (exponent % 10)); (*buffer) = 0; return; } else if (decimal > 0) { // Simple number: A.B for (int i = 0; i < decimal; ++i) (*buffer++) = (*end++); if (decimal < digitCount) (*buffer++) = '.'; count = digitCount - decimal; } else if (decimal < -digitCount) { // What case is this? decimal = count = 0; } else if (decimal < 0 || (decimal == 0 && *end != '0')) { // Tiny number: 0.Me-X (*buffer++) = '0'; (*buffer++) = '.'; for (int i = 0; i < -decimal; ++i) (*buffer++) = '0'; count = digitCount + decimal; } for (; count > 0; --count) if (end[count - 1] != '0') break; for (int i = 0; i < count; ++i) (*buffer++) = (*end++); if (decimal == 0 && count == 0) (*buffer++) = '0'; if (buffer[-1] == '.') --buffer; (*buffer) = 0; }
void main() { double x,leer_double(); int n,signo,d,leer_entero(); char *p; x = leer_double(); /* Lee un dato de tipo double */ /* Ver funcion leer_double() */ d = leer_entero(); /* Lee un dato de tipo entero */ /* Ver funcion leer_entero() */ p = ecvt (x,d,&n,&signo); printf ("%s %d %d\n",p,n,signo); getch(); }
RGString RGXmlDataTotalDigits :: BuildString (const RGPScalar& p, int& param1, int& param2) { int totalDigits = SizeLimit; char* str; double d = p.GetDouble (); int decimalPoint; int sign; str = ecvt (d, totalDigits, &decimalPoint, &sign); RGString Result = str; param1 = decimalPoint; param2 = sign; return Result; }
void uninitvar(int fd) { int x; char buf[2]; int decimal, sign; double d; void *p; // cppcheck-suppress uninitvar write(x,"ab",2); // cppcheck-suppress uninitvar write(fd,buf,2); // #6325 // cppcheck-suppress uninitvar write(fd,"ab",x); // cppcheck-suppress uninitvar write(fd,p,2); /* int regcomp(regex_t *restrict preg, const char *restrict pattern, int cflags); */ regex_t reg; const char * pattern; int cflags; // cppcheck-suppress uninitvar regcomp(®, pattern, cflags); pattern=""; // cppcheck-suppress uninitvar regcomp(®, pattern, cflags); regerror(0, ®, 0, 0); // cppcheck-suppress uninitvar // cppcheck-suppress unreadVariable // cppcheck-suppress ecvtCalled char *buffer = ecvt(d, 11, &decimal, &sign); // cppcheck-suppress gcvtCalled gcvt(3.141, 2, buf); char *filename; struct utimbuf *times; // cppcheck-suppress uninitvar // cppcheck-suppress utimeCalled utime(filename, times); struct timeval times1[2]; // cppcheck-suppress uninitvar // cppcheck-suppress utimeCalled utime(filename, times1); }
char * _RTL_FUNC _ecvt(double val, int len, int *decimal, int *sign) { return ecvt(val, len, decimal, sign); }
inline char* _Stl_qecvtR(long double x, int n, int* pt, int* sign, char* ) { return ecvt( x, n, pt, sign ); }
inline char* _Stl_ecvtR(double x, int n, int* pt, int* sign, char* buf) { return ecvt(x, n, pt, sign); }
static std::string doubleToString(double d, int precision, DoubleForm form, int width, unsigned flags) { std::string num_str; if (precision == -1) { precision = 6; } if (width == -1) { width = 0; } bool negative = false; bool special_number = false; // nan, +/- inf if (std::isinf(d)) { num_str = "inf"; special_number = true; negative = d < 0; } if (std::isnan(d)) { num_str = "nan"; special_number = true; } if (!special_number) { int decpt, sign; std::string digits; if (form == DFDecimal) { digits = std::string(fcvt(d, precision, &decpt, &sign)); } else { int pr = precision; if (form == DFExponent) ++pr; else if (form == DFSignificantDigits && pr == 0) pr = 1; digits = std::string(ecvt(d, pr, &decpt, &sign)); // Chop the trailing zeros. if (digits.length() > 0) { int last_nonzero_idx = digits.length() - 1; while (last_nonzero_idx > 0 && digits[last_nonzero_idx] == '0') { --last_nonzero_idx; } digits = digits.substr(0, last_nonzero_idx + 1); } } // char _zero = '0'; // bool always_show_decpt = ((flags & Alternate) || (flags & ForcePoint)); bool always_show_decpt = true; switch (form) { case DFExponent: num_str = exponentForm(digits, decpt, precision, PMDecimalDigits, always_show_decpt); break; case DFDecimal: num_str = decimalForm(digits, decpt, precision, PMDecimalDigits, always_show_decpt); // Chop the trailing zeros. if (num_str.length() > 0) { int last_nonzero_idx = num_str.length() - 1; while (last_nonzero_idx > 0 && num_str[last_nonzero_idx] == '0') { --last_nonzero_idx; } num_str = num_str.substr(0, last_nonzero_idx + 1); if (num_str[num_str.length() - 1] == '.') num_str.append("0"); } break; case DFSignificantDigits: { PrecisionMode mode = (flags & Alternate) ? PMSignificaintDigits : PMChopTrailingZeros; if (decpt != static_cast<int>(digits.length()) && (decpt <= -4 || decpt > precision)) num_str = exponentForm(digits, decpt, precision, mode, always_show_decpt); else num_str = decimalForm(digits, decpt, precision, mode, always_show_decpt); break; } }; negative = sign != 0 && (d != 0.0 || d != -0.0); } if (negative) num_str.insert(0, "-"); else if (flags & AlwaysShowSign) num_str.insert(0, "+"); else if (flags & BlankBeforePositive) num_str.insert(0, " "); return num_str; }
/* * Convert a floating point number to a string formats 'f', 'e' or 'E'. * The result is placed in buf, and len denotes the length of the string * The sign is returned in the is_negative argument (and is not placed * in buf). Always add decimal point if add_dp is YES. */ static char * conv_fp(char format, double num, boolean_e add_dp, int precision, bool_int * is_negative, char buf[], int *len) { char *s = buf; char *p; int decimal_point; if (format == 'f') p = fcvt(num, precision, &decimal_point, is_negative); else /* either e or E format */ p = ecvt(num, precision + 1, &decimal_point, is_negative); /* * Check for Infinity and NaN */ if (isalpha(*p)) { *len = strlen(strcpy(buf, p)); *is_negative = FALSE; return (buf); } if (format == 'f') if (decimal_point <= 0) { *s++ = '0'; if (precision > 0) { *s++ = '.'; while (decimal_point++ < 0) *s++ = '0'; } else if (add_dp) *s++ = '.'; } else { while (decimal_point-- > 0) *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } else { *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } /* * copy the rest of p, the NUL is NOT copied */ while (*p) *s++ = *p++; if (format != 'f') { char temp[EXPONENT_LENGTH]; /* for exponent conversion */ int t_len; bool_int exponent_is_negative; *s++ = format; /* either e or E */ decimal_point--; if (decimal_point != 0) { p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative, &temp[EXPONENT_LENGTH], &t_len); *s++ = exponent_is_negative ? '-' : '+'; /* * Make sure the exponent has at least 2 digits */ if (t_len == 1) *s++ = '0'; while (t_len--) *s++ = *p++; } else { *s++ = '+'; *s++ = '0'; *s++ = '0'; } } *len = s - buf; return (buf); }
//----------------------------------------------------------------------------- // Name: WindowProc() // Desc: The Main Window Procedure //----------------------------------------------------------------------------- long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { char str2[40]; char *ss; int dec,sign,xpos,pp; switch (message) { case WM_ACTIVATEAPP: // Pause if minimized or not the top window g_bActive = (wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE); return 0L; break; case WM_DESTROY: // Clean up and close the app ADmainExit(); PostQuitMessage(0); return 0L; break; case WM_PAINT: // if (video.enabled) ADmainLoop(); break; case WM_SIZE: if (!RunFullscreen) { //wnWidth = LOWORD(lParam); //wnHeight = HIWORD(lParam); // if (video.enabled) ADmainLoop(); } break; case WM_LBUTTONDOWN: if (demoRunning) { PostMessage(hWnd, WM_CLOSE, 0, 0); return 0L; } break; /* case WM_MOUSEMOVE: if (demoRunning) { xpos = LOWORD(lParam); if (xpos>mouseop) { curpos+=0.001; if (curpos>1) curpos=1; } else { curpos-=0.001; if (curpos<0) curpos=0; } mouseop=xpos; } */ case WM_KEYDOWN: // Handle any non-accelerated key commands if (demoRunning) switch (wParam) { case VK_F2: curpos-=0.02f; if (curpos<0) curpos=0; break; case VK_F3: curpos+=0.02f; if (curpos>1) curpos=1; break; case VK_F4: curpos=1.0; break; case VK_F5: // ss=str1; ss=ecvt(curpos, 8, &dec, &sign); strcpy(str2,"pos: 0."); dec=abs(dec); for (pp=0; pp<dec; pp++) strcat(str2, "0"); strcat(str2,ss); MessageBox(miawin, str2, "AD-Tuning System", NULL); break; case VK_ESCAPE: case VK_F12: // PostMessage(hWnd, WM_CLOSE, 0, 0); demo_state=1; return 0L; break; } break; case WM_SETCURSOR: // Turn off the cursor if this is a full-screen app if (RunFullscreen) SetCursor(NULL); else SetCursor(miocursor); return TRUE; break; } return DefWindowProc(hWnd, message, wParam, lParam); }
/* * Convert a floating point number to a string formats 'f', 'e' or 'E'. * The result is placed in buf, and len denotes the length of the string * The sign is returned in the is_negative argument (and is not placed * in buf). */ static char *conv_fp(register char format, register double num, boolean_e add_dp, int precision, int *is_negative, char *buf, size_t *len) { register char *s = buf; register char *p; int decimal_point; char buf1[NDIG]; if (format == 'f') p = fcvt(num, precision, &decimal_point, is_negative, buf1); else /* either e or E format */ p = ecvt(num, precision + 1, &decimal_point, is_negative, buf1); /* * Check for Infinity and NaN */ if (isalpha(*p)) { *len = strlen(p); memcpy(buf, p, *len + 1); *is_negative = FALSE; return (buf); } if (format == 'f') { if (decimal_point <= 0) { *s++ = '0'; if (precision > 0) { *s++ = '.'; while (decimal_point++ < 0) *s++ = '0'; } else if (add_dp) *s++ = '.'; } else { while (decimal_point-- > 0) *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } } else { *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } /* * copy the rest of p, the NUL is NOT copied */ while (*p) *s++ = *p++; if (format != 'f') { char temp[EXPONENT_LENGTH]; /* for exponent conversion */ size_t t_len; int exponent_is_negative; *s++ = format; /* either e or E */ // // XXX: without the check the routine converts 0.0 to "0.0e-1" // if (num != 0.0) decimal_point--; if (decimal_point != 0) { p = conv_10((int32_t) decimal_point, FALSE, &exponent_is_negative, &temp[EXPONENT_LENGTH], &t_len); *s++ = exponent_is_negative ? '-' : '+'; /* * Make sure the exponent has at least 2 digits */ if (t_len == 1) *s++ = '0'; while (t_len--) *s++ = *p++; } else { *s++ = '+'; *s++ = '0'; *s++ = '0'; } } *len = s - buf; return (buf); }
/* function to read in the global imagery based on the wavelengths provided and a yymm integer supplied by the user. The arrays are populated here and made available to the rest of the code as static floats */ static void read_global_imagery(void){ int size, i, decimal, negative; int strlen=3; char nLw_image_filename[100]; char *lambda; gzFile file; /* initialise the arrays based on the user input of width and height */ size = width*height*sizeof(float); nLw412 = malloc(size); nLw443 = malloc(size); nLw490 = malloc(size); nLw510 = malloc(size); nLw555 = malloc(size); nLw670 = malloc(size); /* use fwave in here to read in the various bands */ for (i=0;i<NB;i++){ /* convert the float (fwave) to a string (lambda) */ lambda = ecvt(fwave[i],strlen,&decimal,&negative); /* nLw image filename based on wavelength and yymm */ sprintf(nLw_image_filename,"%s/nLw_%s_%04d.flw.gz",INDIR,lambda,yymm); if (nLw_image_filename == NULL){ fprintf(stderr,"Need to enter correct filename\n"); exit(1); } printf("Reading in: %s\n", nLw_image_filename); if ((file = gzopen(nLw_image_filename, "rb")) == NULL) { fprintf(stderr, "Could not open %s\n", nLw_image_filename); exit(1); } /* switch based on wavelength (currently set to SeaWiFS bands) */ switch((int)fwave[i]){ case 412: if (gzread(file, nLw412, size) != size) { fprintf(stderr, "Could not read image from %s (file too small?)\n", nLw_image_filename); gzclose(file); exit(1); } break; case 443: if (gzread(file, nLw443, size) != size) { fprintf(stderr, "Could not read image from %s (file too small?)\n", nLw_image_filename); gzclose(file); exit(1); } break; case 490: if (gzread(file, nLw490, size) != size) { fprintf(stderr, "Could not read image from %s (file too small?)\n", nLw_image_filename); gzclose(file); exit(1); } break; case 510: if (gzread(file, nLw510, size) != size) { fprintf(stderr, "Could not read image from %s (file too small?)\n", nLw_image_filename); gzclose(file); exit(1); } break; case 555: if (gzread(file, nLw555, size) != size) { fprintf(stderr, "Could not read image from %s (file too small?)\n", nLw_image_filename); gzclose(file); exit(1); } break; case 670: if (gzread(file, nLw670, size) != size) { fprintf(stderr, "Could not read image from %s (file too small?)\n", nLw_image_filename); gzclose(file); exit(1); } break; default: printf("No such wavelength\n"); break; } /* close the file */ gzclose(file); } }
/* Need to write out global imagery */ static void write_global_imagery() { int i,size,pixel,decimal,negative; int strlen=3; char *lambda; char atot_image_filename[100]; char aph_image_filename[100]; char ady_image_filename[100]; char bb_image_filename[100]; char tc_image_filename[100]; char aph_ratio_image_filename[100]; float *atot_lambda, *aph_lambda, *ady_lambda, *bb_lambda; gzFile *atot_file, *aph_file, *ady_file, *bb_file, *tc_file, *aph_ratio_file; size = width*height*sizeof(float); for(i=0;i<NB;i++){ atot_lambda = malloc(width*height*sizeof(float)); aph_lambda = malloc(width*height*sizeof(float)); ady_lambda = malloc(width*height*sizeof(float)); bb_lambda = malloc(width*height*sizeof(float)); lambda = ecvt(fwave[i],strlen,&decimal,&negative); /* IOP image filename based on wavelength and yymm */ printf("Creating IOP outputs at %s nm ...\n", lambda); sprintf(atot_image_filename,"%s/atot_%s_%04d.flw.gz",OUTDIR,lambda,yymm); sprintf(aph_image_filename,"%s/aph_%s_%04d.flw.gz",OUTDIR,lambda,yymm); sprintf(ady_image_filename,"%s/ady_%s_%04d.flw.gz",OUTDIR,lambda,yymm); sprintf(bb_image_filename,"%s/bb_%s_%04d.flw.gz",OUTDIR,lambda,yymm); /* printf("%s\n",atot_image_filename); printf("%s\n",aph_image_filename); printf("%s\n",ady_image_filename); printf("%s\n",bb_image_filename); */ if ((atot_file = gzopen(atot_image_filename, "wb")) == NULL) { fprintf(stderr, "Could not open %s\n", atot_image_filename); exit(1); } if ((aph_file = gzopen(aph_image_filename, "wb")) == NULL) { fprintf(stderr, "Could not open %s\n", aph_image_filename); exit(1); } if ((ady_file = gzopen(ady_image_filename, "wb")) == NULL) { fprintf(stderr, "Could not open %s\n", ady_image_filename); exit(1); } if ((bb_file = gzopen(bb_image_filename, "wb")) == NULL) { fprintf(stderr, "Could not open %s\n", bb_image_filename); exit(1); } /* retrieve the individual bands from the BIP created in main function */ for(pixel=0;pixel<width*height;pixel++){ atot_lambda[pixel] = atot[(pixel*NB)+i]; aph_lambda[pixel] = aph[(pixel*NB)+i]; ady_lambda[pixel] = adg[(pixel*NB)+i]; bb_lambda[pixel] = bb[(pixel*NB)+i]; } /* now write out to file */ gzwrite(atot_file, atot_lambda, size); gzwrite(aph_file, aph_lambda, size); gzwrite(ady_file, ady_lambda, size); gzwrite(bb_file, bb_lambda, size); /* close the files */ gzclose(atot_file); gzclose(aph_file); gzclose(ady_file); gzclose(bb_file); /* free up the temporary array memory */ free(atot_lambda); free(aph_lambda); free(ady_lambda); free(bb_lambda); } /* write out the global total-chlorophyll product and absorption ratio */ sprintf(tc_image_filename,"%s/tc_%04d.flw.gz",OUTDIR,yymm); sprintf(aph_ratio_image_filename,"%s/aph_ratio_%04d.flw.gz",OUTDIR,yymm); if ((tc_file = gzopen(tc_image_filename, "wb")) == NULL) { fprintf(stderr, "Could not open %s\n", tc_image_filename); exit(1); } if ((aph_ratio_file = gzopen(aph_ratio_image_filename, "wb")) == NULL) { fprintf(stderr, "Could not open %s\n", aph_ratio_image_filename); exit(1); } /* now write out to file */ gzwrite(tc_file,TC,size); gzwrite(aph_ratio_file,aph_ratio,size); /* close the files */ gzclose(tc_file); gzclose(aph_ratio_file); /* free up the BIP memory created in the main routine */ free(atot); free(aph); free(adg); free(bb); free(TC); free(aph_ratio); }
void format (struct obstack *obs, int argc, token_data **argv) { #ifdef HAVE_EFGCVT const char *fmt; /* format control string */ int c; /* a simple character */ char fc; /* format code */ /* Flags. */ char flags; /* 1 iff treating flags */ char ljust; /* left justification */ char mandsign; /* mandatory sign */ char noplus; /* use space if no sign */ char alternate; /* use alternate form */ char zeropad; /* do zero padding */ char plus; /* plus-sign, according to mandatory and noplus */ /* Precision specifiers. */ int width; /* minimum field width */ int prec; /* precision */ int maxch; /* maximum no. of chars to print */ char lflag; /* long flag */ char hflag; /* short flag */ /* Different parts of each specification. */ char sign; /* wanted sign, iff any */ int ppad; /* pre-prefix zero padding */ const char *prefix; /* value prefix */ int lpad; /* zero padding on the left */ register char *s; /* ptr to formatted text */ int rpad; /* zero padding on the rigth*/ const char *suffix; /* value suffix */ /* Buffer and stuff. */ char str[MAXFIELD]; /* buffer for formatted text */ int length; /* length of str */ int padding; /* padding at the left or rigth */ register int i; /* an index */ /* Length of trailing string in str. */ #define LENGTH(s) (&str[MAXFIELD-1] - (s)) #define HAS_SIGN (sign != '\0') fmt = ARG_STR (argc, argv); for (;;) { while ((c = *fmt++) != '%') { if (c == 0) return; obstack_1grow (obs, c); } if (*fmt == '%') { obstack_1grow (obs, '%'); fmt++; continue; } /* Parse flags. */ flags = 1; ljust = mandsign = noplus = alternate = zeropad = 0; do { switch (*fmt) { case '-': /* left justification */ ljust = 1; break; case '+': /* mandatory sign */ mandsign = 1; break; case ' ': /* space instead of positive sign */ noplus = 1; break; case '0': /* zero padding */ zeropad = 1; break; case '#': /* alternate output */ alternate = 1; break; default: flags = 0; break; } } while (flags && fmt++); plus = '\0'; /* what to use as a plus ??? */ if (mandsign) plus = '+'; else if (noplus) plus = ' '; if (ljust) zeropad = 0; /* Minimum field width. */ width = -1; if (*fmt == '*') { width = ARG_INT (argc, argv); fmt++; } else if (isdigit (*fmt)) { width = 0; do { width = width * 10 + *fmt++ - '0'; } while (isdigit (*fmt)); } /* Maximum precision. */ prec = -1; if (*fmt == '.') { if (*(++fmt) == '*') { prec = ARG_INT (argc, argv); ++fmt; } else if (isdigit (*fmt)) { prec = 0; do { prec = prec * 10 + *fmt++ - '0'; } while (isdigit (*fmt)) ; } } /* Length modifiers. */ lflag = (*fmt == 'l'); hflag = (*fmt == 'h'); if (lflag || hflag) fmt++; sign = '\0'; ppad = lpad = rpad = 0; maxch = -1; prefix = suffix = ""; switch (fc = *fmt++) { case '\0': return; case 'c': c = ARG_INT (argc, argv); str[0] = (unsigned char) c; str[1] = '\0'; s = str; break; case 's': s = ARG_STR (argc, argv); maxch = prec; break; case 'd': case 'i': if (lflag) { long val = ARG_LONG (argc, argv); if (val < 0) { val = -val; /* does not work for MINLONG */ sign = '-'; } else sign = plus; s = ulong_to_str ((unsigned long) val, str, 10, digits); } else { int val = ARG_INT (argc, argv); if (hflag) val = (short) val; if (val < 0) { val = -val; /* does not work for MININT */ sign = '-'; } else sign = plus; s = ulong_to_str ((unsigned long) val, str, 10, digits); } if (zeropad) lpad = width - LENGTH (s) - HAS_SIGN; break; case 'o': if (lflag) { unsigned long val = ARG_ULONG (argc, argv); s = ulong_to_str ((unsigned long) val, str, 8, digits); } else { unsigned int val = ARG_UINT (argc, argv); if (hflag) val = (unsigned short) val; s = ulong_to_str ((unsigned long) val, str, 8, digits); } if (alternate) prefix = "0"; if (zeropad) lpad = width - LENGTH (s) - alternate; break; case 'x': case 'X': if (lflag) { unsigned long val = ARG_ULONG (argc, argv); s = ulong_to_str ((unsigned long) val, str, 16, (fc == 'x') ? digits : Digits); } else { unsigned int val = ARG_UINT (argc, argv); if (hflag) val = (unsigned short) val; s = ulong_to_str ((unsigned long) val, str, 16, (fc == 'x') ? digits : Digits); } if (alternate) prefix = (fc == 'X') ? "0X" : "0x"; if (zeropad) lpad = width - LENGTH (s) - 2*alternate; break; case 'u': if (lflag) { unsigned long val = ARG_ULONG (argc, argv); s = ulong_to_str ((unsigned long) val, str, 10, digits); } else { unsigned int val = ARG_UINT (argc, argv); if (hflag) val = (unsigned short) val; s = ulong_to_str ((unsigned long) val, str, 10, digits); } if (zeropad) lpad = width - LENGTH (s); break; case 'e': case 'E': { char *t; int sgn, decpt, exp, n; double val = ARG_DOUBLE (argc, argv); if (prec < 0) prec = 6; t = clr0 (ecvt (val, min (prec + 1, ECVTMAX), &decpt, &sgn)); sign = sgn ? '-' : plus; n = prec; s = str; exp = (t[0] == '0' && t[1] == '\0') ? 0 : decpt - 1; *s++ = *t++; if (n > 0 || alternate) *s++ = '.'; while (*t != '\0' && --n >= 0) *s++ = *t++; *s = '\0'; rpad = n; sgn = 0; if (exp < 0) { exp = -exp; sgn = 1; } t = ulong_to_str ((unsigned long) exp, str, 10, digits); if (exp < 10) *--t = '0'; /* always at least two digits */ *--t = sgn ? '-' : '+'; *--t = fc; if (zeropad) { lpad = width - HAS_SIGN - (s - str) - LENGTH (t); if (rpad > 0) lpad -= rpad; } suffix = t; s = str; } break; case 'f': { const char *t; int sgn, decpt, n; double val = ARG_DOUBLE (argc, argv); if (prec < 0) prec = 6; /* FIXME: For the following line, Dave Anglin reports ``warning: passing arg 1 of `clr0' discards `const' from pointer target type''. I suspect fcvt might be declared as returning const on some systems. Pouah! I should revise this whole module, one of these days... */ t = clr0 (fcvt (val, min (prec, FCVTMAX), &decpt, &sgn)); sign = sgn ? '-' : plus; n = prec; s = str; if (decpt <= 0) { prefix = (n > 0 || alternate) ? "0." : "0"; lpad = min (-decpt, prec); n -= lpad; } else { while (--decpt >= 0) *s++ = *t++; if (n > 0 || alternate) *s++ = '.'; } while (*t && --n >= 0) *s++ = *t++; *s = '\0'; rpad = n; if (zeropad) ppad = width - HAS_SIGN - (prefix[1] ? 2 : 1) - lpad - (s - str) - rpad; s = str; } break; default: continue; } if (lpad < 0) lpad = 0; if (rpad < 0) rpad = 0; if (width < 0) width = 0; i = strlen (s); if (maxch <= 0 || maxch > i) maxch = i; length = (HAS_SIGN + ppad + strlen (prefix) + lpad + maxch + rpad + strlen (suffix)); padding = 0; if (width != 0) { padding = width - length; } if (ljust == 0) /* left padding */ for (i = padding; --i >= 0;) obstack_1grow (obs, ' '); if (HAS_SIGN) /* sign */ obstack_1grow (obs, sign); for (i = ppad; --i >= 0;) /* pre-prefix zero padding */ obstack_1grow (obs, '0'); for (; *prefix; ++prefix) /* prefix */ obstack_1grow (obs, *prefix); for (i = lpad; --i >= 0;) /* left zero padding */ obstack_1grow (obs, '0'); for (i = maxch; --i >= 0; ++s) /* actual text */ obstack_1grow (obs, *s); for (i = rpad; --i >= 0;) /* right zero padding */ obstack_1grow (obs, '0'); for (; *suffix; ++suffix) /* suffix */ obstack_1grow (obs, *suffix); if (ljust != 0) /* right padding */ for (i = padding; --i >= 0;) obstack_1grow (obs, ' '); } #else /* not HAVE_EFGCVT */ char *fmt; /* format control string */ const char *fstart; /* beginning of current format spec */ int c; /* a simple character */ /* Flags. */ char flags; /* 1 iff treating flags */ /* Precision specifiers. */ int width; /* minimum field width */ int prec; /* precision */ char lflag; /* long flag */ char hflag; /* short flag */ /* Buffer and stuff. */ char str[256]; /* buffer for formatted text */ enum {INT, UINT, LONG, ULONG, DOUBLE, STR} datatype; fmt = ARG_STR (argc, argv); for (;;) { while ((c = *fmt++) != '%') { if (c == 0) return; obstack_1grow (obs, c); } fstart = fmt - 1; if (*fmt == '%') { obstack_1grow (obs, '%'); fmt++; continue; } /* Parse flags. */ flags = 1; do { switch (*fmt) { case '-': /* left justification */ case '+': /* mandatory sign */ case ' ': /* space instead of positive sign */ case '0': /* zero padding */ case '#': /* alternate output */ break; default: flags = 0; break; } } while (flags && fmt++); /* Minimum field width. */ width = -1; if (*fmt == '*') { width = ARG_INT (argc, argv); fmt++; } else if (isdigit (*fmt)) { do { fmt++; } while (isdigit (*fmt)); } /* Maximum precision. */ prec = -1; if (*fmt == '.') { if (*(++fmt) == '*') { prec = ARG_INT (argc, argv); ++fmt; } else if (isdigit (*fmt)) { do { fmt++; } while (isdigit (*fmt)); } } /* Length modifiers. */ lflag = (*fmt == 'l'); hflag = (*fmt == 'h'); if (lflag || hflag) fmt++; switch (*fmt++) { case '\0': return; case 'c': datatype = INT; break; case 's': datatype = STR; break; case 'd': case 'i': if (lflag) { datatype = LONG; } else { datatype = INT; } break; case 'o': case 'x': case 'X': case 'u': if (lflag) { datatype = ULONG; } else { datatype = UINT; } break; case 'e': case 'E': case 'f': datatype = DOUBLE; break; default: continue; } c = *fmt; *fmt = '\0'; switch(datatype) { case INT: if (width != -1 && prec != -1) sprintf (str, fstart, width, prec, ARG_INT(argc, argv)); else if (width != -1) sprintf (str, fstart, width, ARG_INT(argc, argv)); else if (prec != -1) sprintf (str, fstart, prec, ARG_INT(argc, argv)); else sprintf (str, fstart, ARG_INT(argc, argv)); break; case UINT: if (width != -1 && prec != -1) sprintf (str, fstart, width, prec, ARG_UINT(argc, argv)); else if (width != -1) sprintf (str, fstart, width, ARG_UINT(argc, argv)); else if (prec != -1) sprintf (str, fstart, prec, ARG_UINT(argc, argv)); else sprintf (str, fstart, ARG_UINT(argc, argv)); break; case LONG: if (width != -1 && prec != -1) sprintf (str, fstart, width, prec, ARG_LONG(argc, argv)); else if (width != -1) sprintf (str, fstart, width, ARG_LONG(argc, argv)); else if (prec != -1) sprintf (str, fstart, prec, ARG_LONG(argc, argv)); else sprintf (str, fstart, ARG_LONG(argc, argv)); break; case ULONG: if (width != -1 && prec != -1) sprintf (str, fstart, width, prec, ARG_ULONG(argc, argv)); else if (width != -1) sprintf (str, fstart, width, ARG_ULONG(argc, argv)); else if (prec != -1) sprintf (str, fstart, prec, ARG_ULONG(argc, argv)); else sprintf (str, fstart, ARG_ULONG(argc, argv)); break; case DOUBLE: if (width != -1 && prec != -1) sprintf (str, fstart, width, prec, ARG_DOUBLE(argc, argv)); else if (width != -1) sprintf (str, fstart, width, ARG_DOUBLE(argc, argv)); else if (prec != -1) sprintf (str, fstart, prec, ARG_DOUBLE(argc, argv)); else sprintf (str, fstart, ARG_DOUBLE(argc, argv)); break; case STR: if (width != -1 && prec != -1) sprintf (str, fstart, width, prec, ARG_STR(argc, argv)); else if (width != -1) sprintf (str, fstart, width, ARG_STR(argc, argv)); else if (prec != -1) sprintf (str, fstart, prec, ARG_STR(argc, argv)); else sprintf (str, fstart, ARG_STR(argc, argv)); break; } *fmt = c; obstack_grow (obs, str, strlen (str)); } #endif /* not HAVE_EFGCVT */ }
char * dtoa(double d, // IN int mode, // IN int prec, // IN int *expOut, // OUT int *sign, // OUT char **strEnd) // OUT { char *str = NULL; int dec; #if defined(_WIN32) if (2 == mode) { str = malloc(_CVTBUFSIZE); if (str) { if (_ecvt_s(str, _CVTBUFSIZE, d, prec, &dec, sign)) { free(str); str = NULL; } } } else { ASSERT(3 == mode); str = malloc(_CVTBUFSIZE); if (str) { if (_fcvt_s(str, _CVTBUFSIZE, d, prec, &dec, sign)) { free(str); str = NULL; } } /* * When the value is not zero but rounds to zero at prec digits, * the Windows fcvt() sometimes returns the empty string and * a negative dec that goes too far (as in -dec > prec). * For example, converting 0.001 with prec 1 results in * the empty string and dec -2. (See bug 253674.) * * We just clamp dec to -prec when this happens. * * While this may appear to be a safe and good thing to * do in general. It really only works when the result is * all zeros or empty. Since checking for all zeros is * expensive, we only check for empty string, which works * for this bug. */ if (str && *str == '\0' && dec < 0 && dec < -prec) { dec = -prec; } } #else // _WIN32 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; if (2 == mode) { pthread_mutex_lock(&mutex); str = strdup(ecvt(d, prec, &dec, sign)); pthread_mutex_unlock(&mutex); } else { ASSERT(3 == mode); #ifdef __APPLE__ /* * The Mac fcvt() returns "" when prec is 0, so we have to * compensate. See bug 233530. * While it is conceivable that fcvt(round(d), 1) can return * a string that doesn't end in 0, it doesn't seem to happen * in practice (on the Mac). The problematic case that we * want to avoid is a last digit greater than 4, which requires * rounding up, which we don't want to do, which is why we're * doing the rounding on the number instead of after fcvt() * in the first place. * -- edward */ if (prec == 0) { size_t l; pthread_mutex_lock(&mutex); str = strdup(fcvt(round(d), 1, &dec, sign)); pthread_mutex_unlock(&mutex); if (str) { l = strlen(str); ASSERT(l > 0); l--; ASSERT(str[l] == '0'); str[l] = '\0'; } } else #endif // __APPLE__ { pthread_mutex_lock(&mutex); str = strdup(fcvt(d, prec, &dec, sign)); pthread_mutex_unlock(&mutex); } } #endif // _WIN32 if (str) { *strEnd = str + strlen(str); /* strip trailing zeroes */ while ((*strEnd > str) && ('0' == *((*strEnd) - 1))) { (*strEnd)--; } *expOut = dec; } return str; }
char *dbl2str (double d, int p, char buf[], int n) { #if 0 /* * <sign> 1 char * <e> 1 char * <sign> 1 char * <exponent> 1-3 chars * * Also, if the field width is less than the precision * (significant digits), then the latter will have to * be decreased in order to avoid over-running the buffer. * * In order to determine the appropriate precision, if it must * be decreased, we need to know whether or not the converted * number will include an exponent, and if so, how many digits * the exponent will include. */ #define STR_SIZE 1023 static char str[STR_SIZE+1]; sprintf (str, "% #*.*g", n, p); strncpy (buf, str, n); buf[n] = 0; #else int decpt, sign; char tmp[MAX_LEN+1]; char e_str[EXP_LEN+1]; char e_cnt; int i = 0, j = 0; memset (e_str, EXP_LEN+1, 1); e_str[0] = 'e'; strcpy (tmp, ecvt (d, n, &decpt, &sign)); buf[i++] = sign? '-' : ' '; e_str[1] = (decpt > 0? '+' : '-'); if (decpt > 0) /* magnitude >= 1? */ { if (p > 0) /* print some digits after decimal point */ { if (decpt+p > n-2) /* need scientific notation */ { int2str (decpt-1, &e_str[2], 2); for (e_cnt = 0; e_str[(int)e_cnt]; e_cnt++); if (e_cnt+2 > n) goto no_room; buf[i++] = tmp[j++]; if (i < n-e_cnt-1) { buf[i++] = '.'; while (i < n-EXP_LEN) buf[i++] = tmp[j++]; } strcpy (&buf[i], e_str); } else /* print out d+p digits */ { for (; decpt > 0; decpt--) buf[i++] = tmp[j++]; buf[i++] = '.'; for (; p > 0; p--) buf[i++] = tmp[j++]; buf[i++] = '\0'; } } else /* not interested in digits after decimal */ { if (decpt > n-1) /* need scientific notation */ { } else while (i < decpt+1) buf[i++] = tmp[j++]; buf[i++] = 0; } } else /* magnitude < 1*/ { if (p > 0) /* */ { if (p+decpt > 0) /* print some digits out */ { if (p-decpt > n-3) /* need scientific notation */ { int2str (-(decpt-1), &e_str[2], 2); for (e_cnt = 0; e_str[(int)e_cnt]; e_cnt++); if (e_cnt+2 > n) goto no_room; buf[i++] = tmp[j++]; if (i < n-e_cnt-1) { buf[i++] = '.'; while (i < n-e_cnt) buf[i++] = tmp[j++]; } strcpy (&buf[i], e_str); } else /* print 0.(-decpt zeroes)(p+decpt digits) */ { buf[i++] = '0'; buf[i++] = '.'; p += decpt; for (; decpt < 0; decpt++) buf[i++] = '0'; for (; p > 0; p--) buf[i++] = tmp[j++]; buf[i++] = '\0'; } } else /* number too small --effectively zero */ { buf[i++] = '0'; buf[i++] = '.'; for (; (i < n) && (p > 0); p--) buf[i++] = '0'; buf[i++] = '\0'; } } else /* effectively zero */ { buf[i++] = '0'; buf[i++] = '\0'; } } return buf; no_room: for (i = 0; i < n; i++) buf[i] = '#'; buf[i++] = '\0'; return buf; #endif }