### Author Topic: is it a c++ number ?  (Read 9009 times)

#### ToutEnMasm

• Member
• Posts: 1190
##### is it a c++ number ?
« on: September 13, 2014, 10:40:57 PM »

I search a function who can answer it is a number for this c++ string numbers:
Quote
;rien = 0x0;
;rien = 0X245f;
;rien = 0X245flu;
;chose = 245u;
;grand = 0x1df56bULL;
;grand = 0x1df56bi64;
;0.2E-01
;reel = 0.1;
;0x7ffffffffi8 I16 I32 i64
;0756 octal
;rien = -1.18E - 38
I have tried the atoi,strtol.. with no result.
One idea ?.

Fa is a musical note to play with CL

#### jj2007

• Member
• Posts: 8832
• Assembler is fun ;-)
##### Re: is it a c++ number ?
« Reply #1 on: September 13, 2014, 11:21:32 PM »
Looks like really malformed stuff. You may have to reformat them a little bit, like eliminating spaces, or adding suffixes that work better than grand ... bULL

Even MasmBasic's MovVal can't interpret some of them:

Guess MACRO arg
MovVal MyR8, arg
PrintLine Str\$(MyR8), Tb\$, arg
ENDM
.data?
MyR8      REAL8 ?

Init
Guess "0x0"
Guess "0X245f"
Guess "0X245flu"
Guess "245u"
Guess "0x1df56bULL"
Guess "0x1df56bi64"
Guess "0.2E-01"
Guess "0.1"
Guess "0x7ffffffffi8"
Guess "0756"
Guess "-1.18E - 38"
Exit
end start

0.0     0x0
9311.000        0X245f
2383982.0       0X245flu
2383982.0       245u
8.041976e+09    0x1df56bULL
8.041972e+09    0x1df56bi64
0.02000000      0.2E-01
0.1000000       0.1
8.727374e+12    0x7ffffffffi8
756.0000        0756
-1.180000e-16   -1.18E - 38

What are these numbers, part of a database? Any documentation for the flu, bULL, fi8 suffixes? It must be fi8 if the number is 8 chars long: 0x7ffffffffi8

#### ToutEnMasm

• Member
• Posts: 1190
##### Re: is it a c++ number ?
« Reply #2 on: September 13, 2014, 11:35:07 PM »
Quote
Looks like really malformed stuff.
All those chains are allowed in c++,you can compile them.
All i want is a function who answer:
Quote
0 ; chain
1 ;number
2 ;it is a real
3 ;it is unsigned ....and so on
Fa is a musical note to play with CL

#### jj2007

• Member
• Posts: 8832
• Assembler is fun ;-)
##### Re: is it a c++ number ?
« Reply #3 on: September 14, 2014, 12:10:12 AM »
All those chains are allowed in c++,you can compile them.

C++ compiles a "chain" that looks like hex but has 9 chars?
0x7ffffffffi8

#### ToutEnMasm

• Member
• Posts: 1190
##### Re: is it a c++ number ?
« Reply #4 on: September 14, 2014, 01:00:37 AM »
compiled without problem

here is my test prog  ,Visual C express edition 2010,cl /c /FA /Gm- /GS- /Zi

Code: [Select]
` // crt_strtod.c // This program uses strtod to convert a // string to a double-precision value; strtol to // convert a string to long integer values; and strtoul // to convert a string to unsigned long-integer values. // #include <stdlib.h> #include <stdio.h> int main( void ) { char   *string, *stopstring; double x; long   l; int    base; unsigned long ul; //string = "-1.18E - 38";//"255";//"0X245flu"; string = "0x7ffffffffi8"; base=atoi(string); base = 0x7ffffffffi8; printf("   atoi = %x\n", base ); x = strtod( string, &stopstring ); printf( "string = %s\n", string ); printf("   strtod = %f\n", x ); printf("   Stopped scan at: %s\n\n", stopstring ); string = "-10110134932This stopped it"; l = strtol( string, &stopstring, 10 ); printf( "string = %s\n", string ); printf("   strtol = %ld\n", l ); printf("   Stopped scan at: %s\n\n", stopstring ); string = "0X245flu"; //"10110134932"; printf( "string = %s\n", string ); // Convert string using base 2, 4, and 8: for( base = 2; base <= 8; base *= 2 ) { // Convert the string: ul = strtoul( string, &stopstring, base ); printf( "   strtol = %ld (base %d)\n", ul, base ); printf( "   Stopped scan at: %s\n", stopstring ); }`
Fa is a musical note to play with CL

#### jj2007

• Member
• Posts: 8832
• Assembler is fun ;-)
##### Re: is it a c++ number ?
« Reply #5 on: September 14, 2014, 01:51:04 AM »
base = 0x7ffffffffi8;
printf("   atoi = %x\n", base );

Using VC 2010 Express, my output is atoi = ffffffff
Does that make sense to you?

#### ToutEnMasm

• Member
• Posts: 1190
##### Re: is it a c++ number ?
« Reply #6 on: September 14, 2014, 04:08:10 AM »

seems that those functions don't accept hexadecimal chain. "stopped ar 0x , stopped at fffff"
That's all I can said.
Fa is a musical note to play with CL

#### jj2007

• Member
• Posts: 8832
• Assembler is fun ;-)
##### Re: is it a c++ number ?
« Reply #7 on: September 14, 2014, 04:59:33 AM »
It's much worse, actually:
base = 0x7ffffffffi8;   // this COMPILES without warnings ...
printf("   atoi = %x\n", base ); // ... and outputs ffffffff, not 7fff...

a) a fat bug in MSVC
b) a feature
c) garbage in, garbage out

#### qWord

• Member
• Posts: 1473
• The base type of a type is the type itself
##### Re: is it a c++ number ?
« Reply #8 on: September 14, 2014, 05:12:37 AM »
Just checking if a string holds a numeric literal shouldn't be that complicated. Below a spaghetti-code-style procedure that also support these MSVS specific (nonstandard) type suffixes (i64,ui64,...).
Code: [Select]
`include \masm32\include\masm32rt.inc.codeMSVC EQU -1stackframe off; accepts C++ integer and FP literals and C99 hexadecimal FP literals.; Leading and trailing whitespaces (ascii <= 20h) are ignored. No size checking is done.; Return: nonzero value if range [begin,end) is a numberic literal.is_numeric_literal proc uses esi edi ebx pbegin: ptr TCHAR,pend: ptr TCHAR push esi push edi push ebx push ebp mov ebp,esp mov esi,PTCHAR ptr [esp+4*4+4] mov edi,PTCHAR ptr [esp+4*4+8] xor ecx,ecx cmp esi,edi jae @end ; esi = ptr next character ; edi = ptr one past end ; ebx = used for digit test ; eax = current digit/character ; ecx = number of valid digits ; skip leading blanks and possible sign call @spaces .if eax == '+' || eax == '-' call @spaces .endif ;/** ; * check first digit ; */ mov ebx,'9'-'0' ; @digit tests for decimal digits cmp esi,edi ; if there is only one char., it can only be a decimal digit jae @F ; special treatment for 0 as first digit cmp eax,'0' je @start_with_zero@@: cmp eax,'.' ; --> FP literal je @F ; test: decimal digit sub eax,'0' .if eax <= ebx or ecx,1 .endif @decimal: ;/** ; *  read up further decimal digits ; */ call @digits ;/* test and process decimal floating point literals */ .if eax == '.'@@: call @digits cmp eax,'e' je @exponent cmp eax,'E' je @exponent jmp @fp_suffix .endif cmp eax,'e' je @exponent cmp eax,'E' je @exponent ;/** ; * The scanned number is an integer literal. ; *  --> test for possible type-suffix ; */@integer_suffix: mov ebx,@next mov edx,eax or edx,100000y .if edx == 'u' call ebx .if edx == 'l' call ebx .if edx == 'l' call ebx .endifIFDEF MSVC .elseif edx == 'i' jmp @FENDIF .endif .elseif edx == 'l' call ebx .if edx == 'l' call ebx .if edx == 'u' call ebx .endif .elseif edx == 'u' call ebx .endifIFDEF MSVC .elseif edx == 'i' || eax == 'I'@@: call ebx .if eax == '6' call ebx cmp eax,'4' jne @fail .elseif eax == '3' call ebx cmp eax,'2' jne @fail .elseif eax == '1' call ebx cmp eax,'6' jne @fail .elseif eax == '8' call ebx .else jmp @fail .endif call ebxENDIF .endif cmp eax,20h ja @fail jna @check_end @end: ;/* the number of succesfully scanned digits (in ECX) determines the result */ mov eax,ecx mov esp,ebp pop ebp pop ebx pop edi pop esi retn 8@next: ; get the next character cmp esi,edi jae @end movzx eax,TCHAR ptr [esi] add esi,TCHAR mov edx,eax or edx,100000y ; to lower case retn 0@start_with_zero: ;/** ; * Get next next char. and test for prefix: ; *   "0x" -> hexadecimal literal ; *   "0b" -> binary literal ; */ movzx eax,TCHAR ptr [esi] add esi,TCHAR mov edx,eax or edx,100000y sub eax,'0' .if edx == 'x' call @hex_digits .if eax == '.' call @hex_digits cmp eax,'p' je @exponent cmp eax,'P' je @exponent jne @fp_suffix .endif cmp eax,'p' je @exponent cmp eax,'P' je @exponent jne @integer_suffix .endif .if edx == 'b' mov ebx,'1'-'0' push @integer_suffix jmp @digits .else ;/** ; * Possible cases: ; *   - octal integer literal ; *   - decimal FP literal with leading zero(s) ; */ or ecx,1 ; count leading zero ;/* scann for '.', 'e' or 'E' (indicates a decimal FP lit.) */ mov edx,esi .while edx < edi movzx eax,TCHAR ptr [edx] cmp eax,'.' je @decimal or eax,100000y cmp eax,'e' je @decimal add edx,TCHAR .endw ;/* it must be an octal integer literal (or invalid) */ mov ebx,'7'-'0' push @integer_suffix jmp @digits .endif @spaces: ; skip whitespace characters (ascii <= 32)@@: cmp esi,edi jae @end ; end of range reached movzx eax,TCHAR ptr [esi] add esi,TCHAR cmp eax,20h jna @B retn 0@@: add ecx,1 @digits: ; scan didigts (decimal, binary or octal) cmp esi,edi jae @end ; end of range reached movzx eax,TCHAR ptr [esi] add esi,TCHAR sub eax,'0' cmp eax,ebx jna @B add eax,'0' retn 0@@: add ecx,1@hex_digits: ; scan hexadecimal digits cmp esi,edi jae @end ; end of range reached movzx eax,TCHAR ptr [esi] mov edx,eax add esi,TCHAR or edx,100000y sub eax,'0' sub edx,'a' cmp eax,'9'-'0' jna @B cmp edx,'f'-'a' jna @B add eax,'0' retn 0 @exponent: ; scan exponent test ecx,ecx je @end ; the number must already have digits! xor ecx,ecx ; zero ECX -> there must be exponent digits for success. cmp esi,edi jae @end ; end of range reached ; skip sign movzx eax,TCHAR ptr [esi] .if eax == '+' || eax == '-' add esi,TCHAR .endif ; get decimal exponent digits mov ebx,'9'-'0' call @digits ; check for FP suffix 'f', 'F', 'l' and 'L'@fp_suffix: or eax,100000y cmp eax,'f' je @check_end cmp eax,'l' je @check_end cmp eax,20h ja @fail @check_end: ; only whitespaces are allowed after the literal@@: cmp esi,edi jae @end movzx eax,TCHAR ptr [esi] add esi,TCHAR cmp eax,20h jna @B@fail: xor eax,eax mov esp,ebp pop ebp pop ebx pop edi pop esi retn 8 is_numeric_literal endpstackframe onlit_test proc uses esi psz: ptr TCHAR mov esi,psz add esi,len(esi) .if rv(is_numeric_literal,psz,esi) print "  valid: " .else print "invalid: " .endif print psz,13,10 ret lit_test endpmain proc fn lit_test,"123" fn lit_test,"123.456" fn lit_test," 123" fn lit_test," 123  " fn lit_test," 123a" fn lit_test," .123f" fn lit_test," .123L " fn lit_test,"123.456E+78" fn lit_test,"-123" fn lit_test,"   -123.  " fn lit_test,"0x123" fn lit_test,"  0x123  " fn lit_test," 0x123." fn lit_test," 0x123. " fn lit_test," 0x12f.4f" fn lit_test," 0xf123.fp+123" fn lit_test," 0xf123.fp123" fn lit_test," 0xf123.fp+123 " fn lit_test," 0xf123.fp+123l " fn lit_test," 0xf123.fp+123F" fn lit_test," 01234567 " fn lit_test," 012345677 " fn lit_test," 0123456789" fn lit_test," 0b1234567 " fn lit_test," 0b1 " fn lit_test," 0b" fn lit_test," 0x" fn lit_test," 0x0" fn lit_test," 0 " fn lit_test,"0" fn lit_test,"00" fn lit_test,"1" fn lit_test," 1" fn lit_test," 1 " fn lit_test,"0b101010111" fn lit_test,"123." fn lit_test,"0x.F" fn lit_test,"0x.0p0" fn lit_test,"1." fn lit_test,"0.0" fn lit_test,"0." fn lit_test,".0" fn lit_test,".0E-123" fn lit_test,"1.0E0" fn lit_test,"1.00E+0" fn lit_test," +.0E0 " fn lit_test," -0XFFFFFFFF " fn lit_test," -0xffffffff " fn lit_test,"0123" fn lit_test,"0x.123p456-" fn lit_test," 5555q" fn lit_test," 123456ull " fn lit_test," 0xff123ul " fn lit_test," -0xff123lu " fn lit_test,"0xff123llu " fn lit_test,"123u" fn lit_test,"456li" fn lit_test,"0777777-" fn lit_test," 0777E+3" fn lit_test,"0123.456" fn lit_test," 0x123fff.ffae" fn lit_test,"0x123fff.ffae+23" fn lit_test,"+9" fn lit_test,"+666ull" fn lit_test,"+666.000l" fn lit_test,"  -  666.999e-666 " fn lit_test," 123i64" fn lit_test,"-123i32" fn lit_test,"0x123fff.23u" fn lit_test,"0x123fff.23i32" fn lit_test,"0x123fffi32" fn lit_test,"0x123fffi16" fn lit_test,"0x123fffi8" fn lit_test,"0x123fffi9" fn lit_test,"0x123fffi64q" fn lit_test,"0x123fffi8 asd" fn lit_test,"00000.000002E-01" fn lit_test," .000000E-01 " fn lit_test,"0.01E-01" fn lit_test,".9u" fn lit_test,".E-1" fn lit_test,"0x0" fn lit_test,"0X245f" fn lit_test,"0X245flu" fn lit_test,"245u" fn lit_test,"0x1df56bULL" fn lit_test,"0x1df56bi64" fn lit_test,"0.2E-01" fn lit_test,"0.1" fn lit_test,"0x7ffffffffi8" fn lit_test,"0x7ffffffffI16" fn lit_test,"0x7ffffffffI32" fn lit_test,"0x7ffffffffI64" fn lit_test,"0x7ffffffffuI32" fn lit_test,"0756" fn lit_test,"-1.18E - 38" fn lit_test,"-1.18E-38" inkey exitmain endpend main`
MREAL macros - when you need floating point arithmetic while assembling!

#### ToutEnMasm

• Member
• Posts: 1190
##### Re: is it a c++ number ?
« Reply #9 on: September 14, 2014, 04:26:37 PM »

Thanks to qword.

Just a question,I don't see what is the masm equivalent to "0xf123.fp+123l" ?.
Fa is a musical note to play with CL

#### ToutEnMasm

• Member
• Posts: 1190
##### Re: is it a c++ number ?
« Reply #10 on: September 14, 2014, 06:29:12 PM »
Here is my own,using the same chains as qword
Code: [Select]
`include \masm32\include\masm32rt.inc.constZEROLOCALES MACRO dernierelocale:REQ mov edx,edi mov ecx,ebp lea edi,dernierelocale sub ecx,edi xor eax,eax shr ecx,2 rep stosd mov edi,edx ENDM hexadecimal equ 1decimal equ 2octal equ 3.datachiffrehexa db "0","1","2","3","4","5","6","7","8","9","A","a","B","b","C","c","D","d","E","e","F","f",0chiffredeci db "0","1","2","3","4","5","6","7","8","9",0chiffreoctal db "0","1","2","3","4","5","6","7",0.code; accepts C++ integer and FP literals and C99 hexadecimal FP literals.;accept only trimmed chain,no space tab at start and end;accept octal,decimal,hexa,real numbers; Leading and trailing whitespaces (ascii <= 20h) are ignored. No size checking is done.; Return: zero chain,1 number;*********************************************************************;################################################################;reçois l'adresse d'une donnée et détermine si c'est un chiffre,oui retourne 1CertificationChiffre PROC uses esi edi ebx adrChiffre:DWORD Local phrase[MAX_PATH]:BYTE Local Efound:DWORD,Lfound,Pointfound,Ifound,Ufound,Pfound,Plusfound,Moinsfound LOCAL  hexa:DWORD,reel,base Local  retour:DWORD,CPT:DWORD ZEROLOCALES CPT ;-------------------------------- ;----------- vérifier la composition -------------- ;le type binaire 011b n'est pas pris en compte ;0 char mov esi,adrChiffre ; xor eax,eax .if byte ptr [esi] == 0 mov retour,0 jmp FindeCertificationChiffre .endif ;----- real case ------------------ invoke lstrcpy,addr phrase,adrChiffre  ;don't modify the lea esi,phrase ;-------------- All in lowercase,no space and no tab inside the chain ------------ mov ecx,"a" - "A" mov edx,esi Trier: .if byte ptr [edx] != 0 mov al,byte ptr [edx] .if al >= "a" && al <= "z" sub al,cl mov [edx],al .endif .if byte ptr [edx] == " " || byte ptr [edx] == 9 ;edx not changed ;esi and edi move text without the start " " or tab push esi mov edi,edx mov esi,edx @@: .if byte ptr [esi] == " " || byte ptr [edx] == 9 inc esi jmp @B .endif .if byte ptr [esi] == 0 mov byte ptr [edi],0 pop esi jmp endfiltre .else @@: movsb .if byte ptr [esi] != 0 jmp @B .endif mov byte ptr [edi],0 .endif pop esi .endif inc edx jmp Trier .endif endfiltre: ;one char .if byte ptr [esi+1] == 0 ;un seul chiffre ;ne peut être que décimal mov al,byte ptr [esi] mov base,decimal call composition mov retour,edx ;0 chain,1 number jmp FindeCertificationChiffre .endif ;count the number of . lea edx,phrase mov ecx,0 @@: .if byte ptr [edx] != 0 && byte ptr [edx] != "." inc edx jmp @B .else .if byte ptr [edx] == "." inc ecx inc edx jmp @B .endif .endif .if ecx > 1 jmp FindeCertificationChiffre .endif .if ecx == 1 mov base,hexadecimal .endif ;--------- skip prefixes ---------------- lea esi,phrase .if byte ptr [esi] == "+" || byte ptr [esi] == "-" @@: inc esi .if byte ptr [esi] == " " || byte ptr [esi] == 9 jmp  @B .endif .endif .if byte ptr [esi] == "0" ;octal inc esi .if base == 0 mov base,octal ;octal .endif .if byte ptr [esi] == "x" || byte ptr [esi] == "X" inc esi .if byte ptr [esi] == 0 mov retour,1 jmp FindeCertificationChiffre .endif mov base,hexadecimal .endif .endif .if base == 0 mov base,decimal .endif ; first char can be only a digit or a . or a x after prefix mov al,byte ptr [esi] .if al != 0 call composition .if edx != 1 ;échec .if byte ptr [esi] != "." jmp FindeCertificationChiffre .endif .endif .else jmp FindeCertificationChiffre .endif ;esi is on the first digit,continue until no digit loopnumber: inc esi mov al,byte ptr [esi] .if al != 0 call composition .if edx != 1 ;Not a digit ;what is ? .if byte ptr [esi] == "E" inc Efound .if Efound > 1 ;not a number jmp FindeCertificationChiffre .endif .elseif byte ptr [esi] == "." inc Pointfound .if Pointfound > 1 jmp FindeCertificationChiffre .endif .elseif byte ptr [esi] =="U" inc Ufound .if Ufound > 1 jmp FindeCertificationChiffre ;compiled allowed but function .. not ok ?????????? .endif ;it is a suffixe,only letter after ,max 2 .if byte ptr [esi + 1] != 0 .if byte ptr [esi + 1] == "L" || byte ptr [esi + 1] == "I" ;do nothing .else jmp FindeCertificationChiffre ;not a number .endif .endif .elseif byte ptr [esi] == "L" inc Lfound .if Lfound > 2 jmp FindeCertificationChiffre ;not a number .endif .if Lfound == 2 .if byte ptr [esi-1] != "L" jmp FindeCertificationChiffre ;not a number .endif .if byte ptr [esi+1] == 0 || byte ptr [esi+1] == "U" ;ne rien faire .else jmp FindeCertificationChiffre ;not a number .endif .endif .if Lfound == 1 .if byte ptr [esi+1] == 0 || byte ptr [esi+1] == "L" || byte ptr [esi+1] == "U" ;do nothing .else jmp FindeCertificationChiffre ;not a number .endif .endif .elseif byte ptr [esi] == "I" inc Ifound .if Ifound > 1 jmp FindeCertificationChiffre .endif .elseif byte ptr [esi] == "P" inc Pfound .if Pfound > 1 jmp FindeCertificationChiffre .endif ;.FP only .if  byte ptr [esi-1] == "F" && byte ptr [esi-2] == "." ;do nothing .else jmp FindeCertificationChiffre .endif .elseif byte ptr [esi] == "+" inc Plusfound .if Plusfound > 1 ;the first had been skipped jmp FindeCertificationChiffre .endif .elseif byte ptr [esi] == "-" inc Moinsfound .if Moinsfound > 1 ;the first had been skipped jmp FindeCertificationChiffre .endif .else ;not a number jmp FindeCertificationChiffre .endif jmp loopnumber .else jmp loopnumber .endif .else mov retour,1 ;it is a number jmp FindeCertificationChiffre .endif mov retour,1 FindeCertificationChiffre:         mov eax,retour mov edx,hexa         retcomposition: xor edx,edx mov ecx,sizeof chiffrehexa ;tableau car hexa .if base == hexadecimal lea edi,chiffrehexa .elseif base == decimal lea edi,chiffredeci .elseif base == octal lea edi,chiffreoctal .endif repnz scasb .if ecx != 0 mov edx,1 .endif ;chiffrehexa db "0","1","2","3","4","5","6","7","8","9","A","a","B","b","C","c","D","d","E","e","F","f",0 retnCertificationChiffre endp;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@lit_test proc uses esi psz: ptr TCHAR .if rv(CertificationChiffre,psz) print "  valid: " .else print "invalid: " .endif print psz,13,10 ret lit_test endpmain proccomment µ fn lit_test,"123" fn lit_test,"123.456" fn lit_test," 123" fn lit_test," 123  " fn lit_test," 123a" fn lit_test," .123f" fn lit_test," .123L " fn lit_test,"123.456E+78" fn lit_test,"-123" fn lit_test,"  -123.  " fn lit_test,"0x123" fn lit_test,"  0x123  " fn lit_test," 0x123." fn lit_test," 0x123. " fn lit_test," 0x12f.4f" fn lit_test," 0xf123.fp+123" fn lit_test," 0xf123.fp123" fn lit_test," 0xf123.fp+123 " fn lit_test," 0xf123.fp+123l " fn lit_test," 0xf123.fp+123F" fn lit_test," 01234567 " fn lit_test," 012345677 " fn lit_test," 0123456789" fn lit_test," 0b1234567 " fn lit_test," 0b1 " fn lit_test," 0b" fn lit_test," 0x" fn lit_test," 0x0" µ fn lit_test," 0 " fn lit_test,"0" fn lit_test,"00" fn lit_test,"1" fn lit_test," 1" fn lit_test," 1 " fn lit_test,"0b101010111" fn lit_test,"123." fn lit_test,"0x.F" fn lit_test,"0x.0p0" fn lit_test,"1." fn lit_test,"0.0" fn lit_test,"0." fn lit_test,".0" fn lit_test,".0E-123" fn lit_test,"1.0E0" fn lit_test,"1.00E+0" fn lit_test," +.0E0 " fn lit_test," -0XFFFFFFFF " fn lit_test," -0xffffffff " fn lit_test,"0123" fn lit_test,"0x.123p456-" fn lit_test," 5555q" fn lit_test," 123456ull " fn lit_test," 0xff123ul " fn lit_test," -0xff123lu " fn lit_test,"0xff123llu " fn lit_test,"123u" fn lit_test,"456li" fn lit_test,"0777777-" fn lit_test," 0777E+3" fn lit_test,"0123.456" fn lit_test," 0x123fff.ffae" fn lit_test,"0x123fff.ffae+23" fn lit_test,"+9" fn lit_test,"+666ull" fn lit_test,"+666.000l" fn lit_test,"  -  666.999e-666 " fn lit_test," 123i64" fn lit_test,"-123i32" fn lit_test,"0x123fff.23u" fn lit_test,"0x123fff.23i32" fn lit_test,"0x123fffi32" fn lit_test,"0x123fffi16" fn lit_test,"0x123fffi8" fn lit_test,"0x123fffi9" fn lit_test,"0x123fffi64q" fn lit_test,"0x123fffi8 asd" fn lit_test,"00000.000002E-01" fn lit_test," .000000E-01 " fn lit_test,"0.01E-01" fn lit_test,".9u" fn lit_test,".E-1" fn lit_test,"0x0" fn lit_test,"0X245f" fn lit_test,"0X245flu" fn lit_test,"245u" fn lit_test,"0x1df56bULL" fn lit_test,"0x1df56bi64" fn lit_test,"0.2E-01" fn lit_test,"0.1" fn lit_test,"0x7ffffffffi8" fn lit_test,"0x7ffffffffI16" fn lit_test,"0x7ffffffffI32" fn lit_test,"0x7ffffffffI64" fn lit_test,"0x7ffffffffuI32" fn lit_test,"0756" fn lit_test,"-1.18E - 38" fn lit_test,"-1.18E-38" inkey exitmain endpend main`
« Last Edit: September 15, 2014, 04:10:53 AM by ToutEnMasm »
Fa is a musical note to play with CL

#### qWord

• Member
• Posts: 1473
• The base type of a type is the type itself
##### Re: is it a c++ number ?
« Reply #11 on: September 14, 2014, 10:12:37 PM »
Just a question,I don't see what is the masm equivalent to "0xf123.fp+123l" ?.
There is no direct equivalent thus conversion is needed. I would convert thus numbers to MASMs hexadecimal initializers (e.g. 3f800000r). However, the literals are only supported by C and not C++, so you might can simply drop the support for them.

I've seen that your above code must reworked because it:
- does reject valid FP numbers starting with a dot (e.g. ".123")
- accepts invalid octal numbers like "0123456789"
- does not recognized the "u" for MSVC integer suffixes (e.g. "uI32")
- accepts "0b", which is invalid
...
MREAL macros - when you need floating point arithmetic while assembling!

#### MichaelW

• Global Moderator
• Member
• Posts: 1209
##### Re: is it a c++ number ?
« Reply #12 on: September 14, 2014, 11:20:07 PM »
The attachment contains a recent adaptation of some old code that I use to verify that an input string, that is supposed to represent a double, is correctly formatted. For engineering calculations I need to guard against incorrectly formatted inputs because they are likely to contain errors, and the CRT conversion functions, because they stop the conversion at the first character that is not recognized as part of a valid number, will silently convert these inputs. It's straight C code, but seems fairly fast. In my tests, running on a Core-i3 and checking the string "123.456e3", I get 433 cycles without optimization and 302 with /O2 /G6.

My code handles doubles only, but I think the method could be easily adapted to integers, or even to ignore trash at the end of the string as the CRT does.

Edit: I missed an obvious optimization. For my work most of the pattern strings will be short, typically "dpd" independent of the number of decimal digits, so the code is faster if I define the valid patterns as:
Code: [Select]
`    static char pats[18][7] = {"d","pd","sd","ded","dpd","spd","desd",                               "pded","sded","sdpd","dpded","pdesd",                               "sdesd","spded","dpdesd","spdesd",                               "sdpded","sdpdesd"};`
Updated the attachment.
« Last Edit: September 15, 2014, 02:13:10 AM by MichaelW »
Well Microsoft, here’s another nice mess you’ve gotten us into.

#### jj2007

• Member
• Posts: 8832
• Assembler is fun ;-)
##### Re: is it a c++ number ?
« Reply #13 on: September 15, 2014, 12:06:01 AM »
- accepts invalid octal numbers like "0123456789"
..
- accepts "0b", which is invalid

I saw that you reject the decimal string "0123456789" - why that? Also, 0b is valid in assembler, not so in C/C++?

qWord     string       MasmBasic
valid:  012345677     valid
invalid:  0123456789    valid
invalid:  0b1234567     valid
valid:  0b1   valid
invalid:  0b    valid
invalid:  0x    invalid
valid:  0x0   valid

Note I am not saying your code is wrong - I am just curious.

#### qWord

• Member
• Posts: 1473
• The base type of a type is the type itself
##### Re: is it a c++ number ?
« Reply #14 on: September 15, 2014, 12:18:49 AM »
I saw that you reject the decimal string "0123456789" - why that? Also, 0b is valid in assembler, not so in C/C++?
C, C++ and Assembler are different languages and thus have different kind of literals/constants.
For C and C++, octal numbers (base 8 ) begins with a zero thus "0123456789" is invalid due to "89". "0b" is valid for MASM because "b" is a suffix, whereas it must be a prefix for C++14 (previous standards and C doesn't support binary literals btw). It is same as that "0x" is not a number.
MREAL macros - when you need floating point arithmetic while assembling!