VAL for integers 
Author Message
 VAL for integers

The following code will scan a string for the first numeric value and
return it as a long integer.

If the number has commas in it, they will be ignored (ie: "5,500" will
return 5500).

For strings where only Integer values are needed, this code is actually
*slightly* faster than the powerbasic VAL() function which uses floating
point intructions internally.

FUNCTION ValL(s AS STRING) AS LONG

#REGISTER NONE  'required for ASM code

  LOCAL sg AS LONG

  sg = STRPTR(s)

  ! push     ESI
  ! push     EDI

  ! mov      ESI, sg           ; get pointer to string handle
  ! mov      ECX, [ESI-4]      ; get size of string data
  ! xor      EAX, EAX
  ! mov      sg, EAX
  ! or       ECX, ECX
  ! jnz      SkipChar
  ! jmp      Done

SkipChar:
  ! lodsb                      ; get a byte
  ! cmp      AL, "+"           ; is it a plus sign?
  ! je       GotStart          ; yes, start here
  ! cmp      AL, "-"           ; is it a negative sign?
  ! je       GotStart          ; yes, start here
  ! cmp      AL, "0"           ; is it below "0"?
  ! jb       NotStart          ; yes, skip it
  ! cmp      AL, "9"           ; is it below/equal "9"?
  ! jbe      GotStart          ; yes, start here

NotStart:
  ! loop     SkipChar          ; skip charactor
  ! jmp      Done              ;

GotStart:
  ! cmp      AL, "+"           ; is first char a plus sign?
  ! jne      CheckMinus        ; no, check for minus sign
  ! dec      ECX               ;
  ! jecxz    Done              ;
  ! jmp      SkipAdjust        ;

CheckMinus:
  ! cmp      AL, "-"           ; is first char a minus sign?
  ! jne      NotNeg            ; no, skip it
  ! mov      Sg, 1             ; yes, it's signed
  ! dec      ECX               ; subtract 1 from length
  ! jecxz    Done              ;
  ! jmp      SkipAdjust        ;

NotNeg:
  ! dec      ESI               ; point to first char

SkipAdjust:
  ! mov      EDI, 10           ; base 10
  ! xor      EAX, EAX          ; clear EAX

Convert:
  ! xor      EBX, EBX          ; clear EBX
  ! mov      BL, [ESI]         ; get a character
  ! cmp      BL, ","           ; is it a comma?
  ! je       NextChar          ; yes, skip it
  ! cmp      BL, "0"           ; is it valid?
  ! jb       Done              ; no, exit
  ! cmp      BL, "9"           ; is it valid?
  ! ja       Done              ; no, exit
  ! sub      BL, "0"           ; convert to binary digit

  ! mul      EDI               ; make room for another digit
  ! add      EAX, EBX          ; add in the digit

NextChar:
  ! inc      ESI               ; move to the next character
  ! loop    Convert            ; do it all ECX times

Done:
  ! cmp     Sg, 0              ; is value signed?
  ! jz      ByeBye             ; no, exit
  ! not     EAX

ByeBye:
  ! pop     EDI
  ! pop     ESI

  ! mov     FUNCTION, EAX

END FUNCTION

FUNCTION PbMain() AS LONG

  a$ = "You owe $5,500 in back taxes."

  PRINT ValL(a$)

END FUNCTION



Tue, 18 Nov 2003 05:39:29 GMT  
 VAL for integers


Quote:
>The following code will scan a string for the first numeric value and
>return it as a long integer.

>If the number has commas in it, they will be ignored (ie: "5,500" will
>return 5500).

>For strings where only Integer values are needed, this code is actually
>*slightly* faster than the PowerBASIC VAL() function which uses floating
>point intructions internally.

<snip>

FUNCTION PbMain() AS LONG

  a$ = "You owe $-5,500 in back taxes."   ' returns -5501
  PRINT ValL(a$)

  WAITEKEY$

END FUNCTION

The above returns -5501 with the latest PBcc.

Is this the fix?

Done:                         ';
  ! cmp     Sg, 0              ; is value signed?
  ! jz      ByeBye             ; no, exit
  ! not     EAX                ;
  ! inc     EAX                ;
  !                            ;    

--
C'ya,

  Don Schullian
www.DASoftVSS.com
www.basicguru.com



Tue, 18 Nov 2003 22:19:56 GMT  
 VAL for integers

Quote:

>   a$ = "You owe $-5,500 in back taxes."   ' returns -5501

> The above returns -5501 with the latest PBcc.

> Is this the fix?

> Done:                         ';
>   ! cmp     Sg, 0              ; is value signed?
>   ! jz      ByeBye             ; no, exit
>   ! not     EAX                ;
>   ! inc     EAX                ;
>   !                            ;    

Oops!  <grin>

Nope, change "not EAX" to "neg EAX" and it will work properly.

--Dave



Fri, 21 Nov 2003 04:17:42 GMT  
 VAL for integers


Quote:
> The following code will scan a string for the first numeric value and
> return it as a long integer.

FUNCTION ValL(s AS STRING) AS LONG

#REGISTER NONE  'required for ASM code

  LOCAL sg AS LONG

  sg = STRPTR(s)

  ! push     ESI
  ! push     EDI

  ! mov      ESI, sg           ; get pointer to string handle
  ! mov      ECX, [ESI-4]      ; get size of string data
  ! xor      EAX, EAX
  ! mov      sg, EAX
  ! or       ECX, ECX
  ! jnz      SkipChar
  ! jmp      Done

SkipChar:
  ! lodsb                      ; get a byte
  ! cmp      AL, "+"           ; is it a plus sign?
  ! je       GotStart          ; yes, start here
  ! cmp      AL, "-"           ; is it a negative sign?
  ! je       GotStart          ; yes, start here
  ! cmp      AL, "0"           ; is it below "0"?
  ! jb       NotStart          ; yes, skip it
  ! cmp      AL, "9"           ; is it below/equal "9"?
  ! jbe      GotStart          ; yes, start here

NotStart:
  ! loop     SkipChar          ; skip charactor
  ! jmp      Done              ;

GotStart:
  ! cmp      AL, "+"           ; is first char a plus sign?
  ! jne      CheckMinus        ; no, check for minus sign
  ! dec      ECX               ;
  ! jecxz    Done              ;
  ! jmp      SkipAdjust        ;

CheckMinus:
  ! cmp      AL, "-"           ; is first char a minus sign?
  ! jne      NotNeg            ; no, skip it
  ! mov      Sg, 1             ; yes, it's signed
  ! dec      ECX               ; subtract 1 from length
  ! jecxz    Done              ;
  ! jmp      SkipAdjust        ;

NotNeg:
  ! dec      ESI               ; point to first char

SkipAdjust:
  ! mov      EDI, 10           ; base 10
  ! xor      EAX, EAX          ; clear EAX

Convert:
  ! xor      EBX, EBX          ; clear EBX
  ! mov      BL, [ESI]         ; get a character
  ! cmp      BL, ","           ; is it a comma?
  ! je       NextChar          ; yes, skip it
  ! cmp      BL, "0"           ; is it valid?
  ! jb       Done              ; no, exit
  ! cmp      BL, "9"           ; is it valid?
  ! ja       Done              ; no, exit
  ! sub      BL, "0"           ; convert to binary digit

  ! mul      EDI               ; make room for another digit
  ! add      EAX, EBX          ; add in the digit

NextChar:
  ! inc      ESI               ; move to the next character
  ! loop    Convert            ; do it all ECX times

Done:
  ! cmp     Sg, 0              ; is value signed?
  ! jz      ByeBye             ; no, exit
  ! neg     EAX                ; convert to negative value

ByeBye:
  ! pop     EDI
  ! pop     ESI

  ! mov     FUNCTION, EAX

END FUNCTION

FUNCTION PbMain() AS LONG

  a$ = "You owe $-5,500 in back taxes."

  PRINT ValL(a$)

END FUNCTION



Fri, 21 Nov 2003 04:19:23 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Near Final PEP 237 - Unifying Long Integers and Integers

2. Revised PEP 237 - Unifying Long Integers and Integers

3. integer/integer division

4. Q: How to typecast integer to array of integers

5. INTEGER*4 --> INTEGER*2

6. It wants INTEGER*1 and NOT INTEGER*2 !?!?

7. How to treat INTEGER as INTEGER*2 in g77

8. integer*1, integer*2 in f90?

9. integer.and.integer

10. integer*8 speed vs integer*4 speed

11. Troubles woith the VAL method

12. VAL decimal convertion

 

 
Powered by phpBB® Forum Software