Determine if a string is numeric: Difference between revisions

Content added Content deleted
(→‎{{header|Vlang}}: Rename "Vlang" in "V (Vlang)")
(Added Z80 Assembly version)
Line 4,940: Line 4,940:
<syntaxhighlight lang="xlisp">(DEFUN NUMERICP (X)
<syntaxhighlight lang="xlisp">(DEFUN NUMERICP (X)
(IF (STRING->NUMBER X) T))</syntaxhighlight>
(IF (STRING->NUMBER X) T))</syntaxhighlight>

=={{header|Z80 Assembly}}==
{{works with|CP/M 3.1|YAZE-AG-2.51.2 Z80 emulator}}
{{works with|ZSM4 macro assembler|YAZE-AG-2.51.2 Z80 emulator}}
Use the /S8 switch on the ZSM4 assembler for 8 significant characters for labels and names
<syntaxhighlight lang="z80">
;
; Check if input string is a number using Z80 assembly language
;
; Runs under CP/M 3.1 on YAZE-AG-2.51.2 Z80 emulator
; Assembled with zsm4 on same emulator/OS, uses macro capabilities of said assembler
; Created with vim under Windows
;
; 2023-04-04 Xorph
;

;
; Useful definitions
;

bdos equ 05h ; Call to CP/M BDOS function
strdel equ 6eh ; Set string delimiter
readstr equ 0ah ; Read string from console
wrtstr equ 09h ; Write string to console

nul equ 00h ; ASCII control characters
esc equ 1bh
cr equ 0dh
lf equ 0ah

cnull equ '0' ; ASCII character constants
cnine equ '9'
cminus equ '-'
cdot equ '.'

buflen equ 30h ; Length of input buffer
minbit equ 00h ; Bit 0 is used as flag for '-'
dotbit equ 01h ; Bit 1 is used as flag for '.'

;
; Macros for BDOS calls
;

setdel macro char ; Set string delimiter to char
ld c,strdel
ld e,char
call bdos
endm

print macro msg ; Output string to console
ld c,wrtstr
ld de,msg
call bdos
endm

newline macro ; Print newline
ld c,wrtstr
ld de,crlf
call bdos
endm

readln macro buf ; Read a line from input
ld c,readstr
ld de,buf
call bdos
endm

;
; =====================
; Start of main program
; =====================
;

cseg

isnum:
setdel nul ; Set string terminator to nul ('\0') - '$' is default in CP/M
print help
newline
newline

readnum:
ld b,buflen ; Clear input buffer
ld hl,bufcont
clrloop:
ld (hl),0
inc hl
djnz clrloop

readln inputbuf ; Read a line from input
newline ; Newline is discarded during input, so write one...

ld a,(inputbuf+1) ; Length of actual input
cp 0 ; If empty input, quit
ret z

ld b,a ; Loop counter for djnz instruction
ld c,0 ; Use c for flags: '-' and '.' may be encountered at most once, '-' only at start
ld hl,bufcont ; Start of actual input

loop:
ld a,(hl) ; Get next character into a

cp cminus ; Check minus sign
jr z,chkminus

cp cdot ; Check dot
jr z,chkdot

cp cnull ; Check if below '0'
jr c,notanum

cp cnine+1 ; Check if above '9'
jr nc,notanum

checknxt:
set minbit,c ; Whatever the case, no more '-' are allowed after the first character
inc hl ; Increase hl to next character and repeat until done
djnz loop

print bufcont ; If we made it this far, we are done and the string is numeric
print yesmsg
newline
newline

done:
jp readnum ; Read next input from user until terminated with ^C or empty input
ret ; Return to CP/M (unreachable code)

notanum:
print bufcont ; Print failure message
print nomsg
newline
newline
jr done

chkminus:
bit minbit,c ; If a '-' is encountered and the flag is already set, the string is not numeric
jr nz,notanum
set minbit,c ; Otherwise, set flag and check next character
jr checknxt

chkdot:
bit dotbit,c ; If a '.' is encountered and the flag is already set, the string is not numeric
jr nz,notanum
set dotbit,c ; Otherwise, set flag and check next character
jr checknxt

;
; ===================
; End of main program
; ===================
;

;
; ================
; Data definitions
; ================
;

dseg

help:
defz 'Enter numbers to check, end with empty line or ^C'

inputbuf: ; Input buffer for CP/M BDOS call
defb buflen ; Maximum possible length
defb 00h ; Returned length of actual input
bufcont:
defs buflen ; Actual input area
defb nul ; Null terminator for output, if buffer is filled completely

yesmsg:
defz ' is numeric'
nomsg:
defz ' is not numeric'

crlf: defb cr,lf,nul ; Generic newline

</syntaxhighlight>

{{out}}
<pre>
E>isnum
Enter numbers to check, end with empty line or ^C

1234
1234 is numeric

hello
hello is not numeric

12.34
12.34 is numeric

-98.76
-98.76 is numeric

4.6.76
4.6.76 is not numeric

34-56-23
34-56-23 is not numeric

-.9876543210
-.9876543210 is numeric

444555.
444555. is numeric

1234c
1234c is not numeric

123e45
123e45 is not numeric

</pre>


=={{header|zkl}}==
=={{header|zkl}}==