MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / decFloatFromString

Function decFloatFromString

extern/decNumber/decCommon.c:776–1006  ·  view source on GitHub ↗

------------------------------------------------------------------ */ decFloatFromString -- conversion from numeric string */ / result is the decFloat format number which gets the result of */ the conversion */ string is the character string which should contain a valid */ number (which may be a special value), \0-terminated */

Source from the content-addressed store, hash-verified

774/* If bad syntax is detected, the result will be a quiet NaN. */
775/* ------------------------------------------------------------------ */
776decFloat * decFloatFromString(decFloat *result, const char *string,
777 decContext *set) {
778 Int digits; // count of digits in coefficient
779 const char *dotchar=NULL; // where dot was found [NULL if none]
780 const char *cfirst=string; // -> first character of decimal part
781 const char *c; // work
782 uByte *ub; // ..
783 uInt uiwork; // for macros
784 bcdnum num; // collects data for finishing
785 uInt error=DEC_Conversion_syntax; // assume the worst
786 uByte buffer[ROUNDUP(DECSTRING+11, 8)]; // room for most coefficents,
787 // some common rounding, +3, & pad
788 #if DECTRACE
789 // printf("FromString %s ...\n", string);
790 #endif
791
792 for(;;) { // once-only 'loop'
793 num.sign=0; // assume non-negative
794 num.msd=buffer; // MSD is here always
795
796 // detect and validate the coefficient, including any leading,
797 // trailing, or embedded '.'
798 // [could test four-at-a-time here (saving 10% for decQuads),
799 // but that risks storage violation because the position of the
800 // terminator is unknown]
801 for (c=string;; c++) { // -> input character
802 if (((unsigned)(*c-'0'))<=9) continue; // '0' through '9' is good
803 if (*c=='\0') break; // most common non-digit
804 if (*c=='.') {
805 if (dotchar!=NULL) break; // not first '.'
806 dotchar=c; // record offset into decimal part
807 continue;}
808 if (c==string) { // first in string...
809 if (*c=='-') { // valid - sign
810 cfirst++;
811 num.sign=DECFLOAT_Sign;
812 continue;}
813 if (*c=='+') { // valid + sign
814 cfirst++;
815 continue;}
816 }
817 // *c is not a digit, terminator, or a valid +, -, or '.'
818 break;
819 } // c loop
820
821 digits=(uInt)(c-cfirst); // digits (+1 if a dot)
822
823 if (digits>0) { // had digits and/or dot
824 const char *clast=c-1; // note last coefficient char position
825 Int exp=0; // exponent accumulator
826 if (*c!='\0') { // something follows the coefficient
827 uInt edig; // unsigned work
828 // had some digits and more to come; expect E[+|-]nnn now
829 const char *firstexp; // exponent first non-zero
830 if (*c!='E' && *c!='e') break;
831 c++; // to (optional) sign
832 if (*c=='-' || *c=='+') c++; // step over sign (c=clast+2)
833 if (*c=='\0') break; // no digits! (e.g., '1.2E')

Callers 1

decFloatNextTowardFunction · 0.85

Calls 2

decBiStrFunction · 0.70
decFinalizeFunction · 0.70

Tested by

no test coverage detected