#

( ud1 -- ud2 )

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:

: GP3 <# 1 0 # # #> S" 01" S= ;
T{ GP3 -> <TRUE> }T

ContributeContributions

mcondronavatar of mcondron 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.

AntonErtlavatar of AntonErtl

# deals with double numbers, and the stack effect reflects that. Not all words dealing with numbers deal with double numbers, e.g., + does not. So the answer to your first question is no.

The result of # goes to the pictured numeric output buffer, and that's the reason why it is required to be used inside <#...#>; <# does not change or look at the data stack. So the answer to your second question is no.

When you call # or #>, there has to be a double on top of the stack. The words are designed such that this is easy to achieve in usual usage, but if you want to use the words in unusual ways, you may have to put more thought into that. It's not necessary to have a double on the stack at all times between <# and #> (as demonstrated in GP3), so technically the answer to your third question is no.

MitraArdronavatar of MitraArdron

Could I suggest that the definition be clarified to at least comment that many earlier versions of Forth used the same words to work on single width numbers.

I think this is one of the few cases in Forth2012 where the same name is used to have a significantly different stack effect from other common forth versions.

CHARS is another example.

PeterKnaggsavatar of PeterKnaggs

Interesting, this definition is inherited directly from the ANS Forth document (1994). The previous standard Forth '83 has the definition:

# +d1 -- +d2 79 "sharp"
The remainder of +d1 divided by the value of BASE is converted to an ASCII character and appended to the output string toward lower memory addresses. +d2 is the quotient and is maintained for further processing. Typically used between <# and #> .

While the Forth '79 standard has:

# ud1 -- ud2 158
Generate from an unsigned double-number d1, the next ASCII character which is placed in an output string. Result d2 is the quotient after division by BASE and is maintained for further processing. Used between <# and #>. "sharp"

Yes it does have ud1 and ud2 in the signature and refer to d1 and d2 in the definition, at least they cleared that up in the '83 standard.

Therefore any system using single cell numbers for # are not and never have been standard. I see no need to refer to old non-standard systems.

PeterKnaggsavatar of PeterKnaggs

I fail to see how CHARS can be considered another example as CHARS was introduced in the ANS Forth Standard document and this definition is inherited directly from that document.

MitraArdronavatar of MitraArdron

I think the systems being referred to are those based on Ting's eForth - these were the only two conflicts I found, where the same name was used with different behavior. <# # #S #> on eForth use single precision numbers, and CHARS outputs a char a multiple number of times. When I was converting webforth over from eForth to Forth2012 both of those conflicts bit me as well.

AntonErtlavatar of AntonErtl

Someone (and it seems that you, MitraArdron feel the itch) could add comments to # and CHARS that warn eforth users that eforth uses non-standard meanings for the respective word.

MitraArdronavatar of MitraArdron

Happy to Anton, but I haven't contributed any text to the standard yet, and its not clear how to do this other than adding a Comment, which I think is what we did ... i.e. it ends up in this section where we are discussing. Could you point me in the right direction.

AntonErtlavatar of AntonErtl

Yes, I meant such a comment. The difference from this comment would be that the comment would point out the problem (non-standard behaviour of eforth) right from the start instead of it being buried deep down in our exchange, and that there would also be such a comment for PARSE. And we could close this comment, which I am now doing (you can reopen it if you feel the need).

Closed

MitraArdronavatar of MitraArdron

OK Anton, done - if that matches what you want I'll add it to the other words.

Reply New Version

MitraArdronavatar of MitraArdron 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.

LeonWagneravatar of LeonWagner

Shouldn't the burden be on eForth to document that it is non-standard?

AntonErtlavatar of AntonErtl

Actually # etc. use double numbers in all Forth standards. It seems to me that it's some newer minimal systems (especially with wider cells) that don't want to implement all the prerequisites of a proper double-cell # and therefore choose to change # to work on a single cell.

It's a good idea if such systems document this deviation from standard and common practice, but given that at least one user was not aware of the difference, adding a warning here may be helpful.

It would be an even better idea if these systems used different names for their non-standard words.

TG9541avatar of TG9541

As a maintainer of an old 8bit STC eForth variant I'm taking note of this discussion, and I'm of course thinking about options as using 32 bit math on a 8 or 16bit system is expensive. Before I take a decision, I'd like to clarify what "double" means on the background of the discussion "S>D in the standard, not double word set". I'd like to know what a double is in a system with 32 cells ( I'm reminded of the ambiguities of int and long int with respect to the native word width in the C language).

AntonErtlavatar of AntonErtl

Doubles always use two cells. E.g., on a system with 64-bit cells, a double is 128 bits wide; an ud is in the range 0..2^128-1, a 2s-complement d in the range -2^127..2^127-1.

MitraArdronavatar of MitraArdron

Leon, Anton - Does eForth predate those standards? There seem to be a lot of systems based on it - probably because its one of the few (if not the only) one that is both simple, and relatively complete - I've happily converted webForth which was based on eForth but is now Forth2012 compliant, but this tripped me up as its one of only a couple of places where the same word is used in eForth and Forth2012 with different stack effects. (I was asked to write the opening contribution as a constructive place to document that difference here, so that it doesn't trip other people up).

StephenPelcavatar of StephenPelc

As far as I remember, eForth is later than most Forth standards, all of which use double-precision cells for the <# # #> and friends. Even on 64 bit systems, there is an argument for <# # #> and friends to use double-cell numbers, as this can make floating point conversion more accurate as the mantissa conversion can be arranged to be to 128 bit integers.

The design decisions of eForth and JonesForth should not influence the standard, nor should these be treated as model implementations of anything other than themselves.

AntonErtlavatar of AntonErtl

According to eforth.src, eForth is from 1990, based on bForth from 1990, a decade after Forth-79 standardized # as working on doubles (and all standards since Forth-79 have kept this # (with the only variation that Forth-83 let # work on +d, while Forth-79, Forth-94, and Forth-2012 let it work on ud).

Reply New Version