- ABORT
- ABORT"
- ABS
- ACCEPT
- ACTION-OF
- AGAIN
- ALIGN
- ALIGNED
- ALLOT
- AND
- BASE
- BEGIN
- BL
- BUFFER:
- [
- [CHAR]
- [COMPILE]
- [']
- CASE
- C,
- CELL+
- CELLS
- C@
- CHAR
- CHAR+
- CHARS
- COMPILE,
- CONSTANT
- COUNT
- CR
- CREATE
- C!
- :
- :NONAME
- ,
- C"
- DECIMAL
- DEFER
- DEFER@
- DEFER!
- DEPTH
- DO
- DOES>
- DROP
- DUP
- /
- /MOD
- .R
- .(
- ."
- ELSE
- EMIT
- ENDCASE
- ENDOF
- ENVIRONMENT?
- ERASE
- EVALUATE
- EXECUTE
- EXIT
- =
- FALSE
- FILL
- FIND
- FM/MOD
- @
- HERE
- HEX
- HOLD
- HOLDS
- I
- IF
- IMMEDIATE
- INVERT
- IS
- J
- KEY
- LEAVE
- LITERAL
- LOOP
- LSHIFT
- MARKER
- MAX
- MIN
- MOD
- MOVE
- M*
- -
- NEGATE
- NIP
- OF
- OR
- OVER
- 1-
- 1+
- PAD
- PARSE-NAME
- PARSE
- PICK
- POSTPONE
- +
- +LOOP
- +!
- QUIT
- RECURSE
- REFILL
- REPEAT
- RESTORE-INPUT
- R@
- ROLL
- ROT
- RSHIFT
- R>
- SAVE-INPUT
- SIGN
- SM/REM
- SOURCE-ID
- SOURCE
- SPACE
- SPACES
- STATE
- SWAP
- ;
- S\"
- S"
- S>D
- !
- THEN
- TO
- TRUE
- TUCK
- TYPE
- '
- *
- */
- */MOD
- 2DROP
- 2DUP
- 2/
- 2@
- 2OVER
- 2R@
- 2R>
- 2SWAP
- 2!
- 2*
- 2>R
- U.R
- UM/MOD
- UM*
- UNLOOP
- UNTIL
- UNUSED
- U.
- U<
- U>
- VALUE
- VARIABLE
- WHILE
- WITHIN
- WORD
- XOR
- 0=
- 0<
- 0>
- 0<>
- \
- .
- <
- >
- <>
- #>
- <#
- #
- #S
- (
- ?DO
- ?DUP
- >BODY
- >IN
- >NUMBER
- >R
6.1.0030 # number-sign CORE
Divide ud1 by the number in BASE giving the quotient ud2 and the remainder n. (n is the least significant digit of ud1.) Convert n to external form and add the resulting character to the beginning of the pictured numeric output string. An ambiguous condition exists if # executes outside of a <# #> delimited number conversion.
See:
Testing:
ContributeContributions
mcondron
[84] Cell width for numbersRequest for clarification2019-06-22 13:42:50
In the specification for #, the stack is shown with "ud". Does this mean that the Standard expects all numbers to manipulated internally as double-width? Or is the interface to the data stack supposed to be aware of whether a <# ... #> delimited conversion is in effect? Or is it the programmer's responsibility to manage data inside a <# ... #> conversion to ensure the data stack always has double-wide values? From the example/test given for # (GP3) it seems the latter is expected.
MitraArdron
[182] Note incompatability (double v single) with some older Forth's.Comment2021-03-13 22:39:27
It should be noted that the words <# SIGN # #S #> etc are one of the few places in Forth where words have different stack effects in different Forth versions. Under Forth2012 and some other standards, they operate on double words, in systems based on eForth they work on single numbers.
EricBlake
[404] Possible reference implementationSuggested reference implementation2025-08-18 14:54:18
The standard does not directly provide any word for dividing a double and getting a double quotient and single remainder simultaneously; thus, it is very useful to provide a reference implementation for how to do this. One possibility is to compute a smaller intermediate ud as the dividend to pass to the standard UM/MOD without triggering ambiguous behavior; plus an optimization to avoid the overhead of two divisions when ud is already small enough.
: ud/mod ( ud1 u1 -- u2 ud2 )
\ Compute quotient ud2 and remainder u2 such that ud2*u1+u2=ud1
OVER 0= IF UM/MOD 0 EXIT THEN \ fast version when ud1 fits in single
DUP >R 0 SWAP ( u.lo ud.t1 u1 ) ( R: u1 ) \ create ud.t1 from upper half of ud1
UM/MOD ( u.lo u.remhi u.quohi ) ( R: u1 ) \ perform first division
R> SWAP >R ( ud.t2 u1 ) ( R: u.quohi ) \ create ud.t2 from lower half of ud1 and upper remainder
UM/MOD R> ( u2 ud2 ) \ second division, ud2 constructed from two halves of quotient
;
: # ( ud1 -- ud2 ) \ "number-sign"
BASE @ ud/mod ROT ( ud2 u.rem )
DUP #10 < IF '0' ELSE [ 'A' #10 - ] LITERAL THEN + ( ud2 char )
HOLD
;
Alternatively, using the double word set, and demonstrating a different bit-twiddling technique for branchless conversion of a digit to ASCII:
: # ( ud1 -- ud2 ) \ "number-sign"
2DUP 1 BASE @ M*/ ( ud1 ud2 ) \ determine quotient
2DUP BASE @ NEGATE 1 M*/ 2ROT ( ud2 ud ud1 ) \ ud = -ud2*base
D+ DROP ( ud2 rem ) \ determine remainder
DUP #9 > #7 AND + '0' + ( ud2 char ) \ exploit that 'A' - '9' = 8
HOLD
;