The issue you're describing here is (in ANS Forth terms) "floored" vs.
"symmetric" division. From Section 3.2.2.1 of the Standard:
Division produces a quotient q and a remainder r by dividing operand a by
operand b. Division operations return q, r, or both. The identity b*q + r
= a shall hold for all a and b.
When unsigned integers are divided and the remainder is not zero, q is the
largest integer less than the true quotient.
When signed integers are divided, the remainder is not zero, and a and b
have the same sign, q is the largest integer less than the true
quotient. If only one operand is negative, whether q is rounded toward
negative infinity (floored division) or rounded towards zero (symmetric
division) is implementation defined.
Floored division is integer division in which the remainder carries the
sign of the divisor or is zero, and the quotient is rounded to its
arithmetic floor. Symmetric division is integer division in which the
remainder carries the sign of the dividend or is zero and the quotient is
the mathematical quotient "rounded towards zero" or "truncated". Examples
of each are shown in tables 3.3 and 3.4.
In cases where the operands differ in sign and the rounding direction
matters, a program shall either include code generating the desired form of
division, not relying on the implementation-defined default result, or have
an environmental dependency on the desired rounding direction.
Table 3.3 Floored Division Example
Dividend Divisor Remainder Quotient
10 7 3 1
-10 7 4 -2
10 -7 -4 -2
-10 -7 -3 1
Table 3.4 Symmetric Division Example
Dividend Divisor Remainder Quotient
10 7 3 1
-10 7 -3 -1
10 -7 3 -1
-10 -7 -3 1
FORTH, Inc. has always elected to use symmetric division as the standard
for basic division such as /, as it is what most chips (including the Intel
line) use and hence has less overhead.
In contrast, 2/ is defined as an arithmetic right shift rather than true
division, and is therefore not subject to this distinction.
ANS Forth requires conforming systems to provide both division primitives,
SM/REM (symmetric) and FM/MOD (floored), so people whose programs have a
dependency on one form or the other can adapt easily (e.g. by redefining /
as they wish). SwiftForth does this. Systems are also required to
document which form is used by the basic division operators, and we
do: it's symmetric (see Reference Manual, Table 29, p. 248).
ANS Forth is available in several formats at
ftp://ftp.minerva.com/PUB/X3J14/DPANS94.*.
Cheers,
Elizabeth
At 09:06 AM 5/8/2000 -0700, you wrote:
>Date: Mon, 08 May 2000 08:53:36 -0700
>From: "Rick VanNorman" <rvn_at_forth.com>
>Subject: Re: Binary question
>
> >From: "Michael Kemper" <mikek_at_metretek.com>
> >
> >Rick,
> >I was coding a crc algorithm and ran across this peculiarity. It may be
> >normal operation, but seems inconsistant to me:
> >
> >If I do the following
> >$CEE1289A $100 / h.
> >>$FFCEE129
> >
> >but if I perform the following:
> >$CEE1289A 2/ 2/ 2/ 2/ 2/ 2/ 2/ 2/ h.
> >>$FFCEE128
> >which is what I'd expect from both versions. Both versions bring the sign
> >bit into the result, but the first rounds the result, which I wouldn't
> >expect from the standard "/" word. Is this normal?
>
>Mike,
>
>My expectations are the same as yours, and I was very surprised to find
>the results you cite. Here is the quote straight from Intel's pentium
>instruction reference for the IDIV instruction:
>
><quote>
>
>Non-integral results are truncated (chopped) towards 0. The sign of
>the remainder is always the same as the sign of the dividend.
>The absolute value of the remainder is always less than the
>absolute value of the divisor. Overflow is indicated with
>the #DE (divide error) exception rather than with the OF (overflow) flag.
>
></quote>
>
>I use the IDIV instruction in / so it will (should) behave like this.
>Consider if the "truncated (chopped) towards 0" is implemented in
>hardware without consideration for the sign bit. This would produce
>the exact result we are seeing.
>
>I don't know what the correct answer is. Can anyone run this on
>another 32-bit Forth and report the results?
>
>Thanks,
>
>Rick
>
>
>
===============================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310-372-8493
111 N. Sepulveda Blvd. Fax: +1 310-318-7130
Manhattan Beach, CA 90266
http://www.forth.com
"Forth-based products and Services for real-time
applications since 1973."
===============================================
.
>From mhx_at_iae.nl Mon May 8 20:31:16 2000
To: sftalk_at_forth.com
Message-Id: <m0000867_at_gerd.forthinc.com>
Date: Mon, 8 May 2000 20:31:16 +0200 (CEST)
From: mhx_at_iae.nl (Marcel Hendrix)
Subject: Re: [sftalk] Binary question
"Rick VanNorman" <rvn_at_forth.com> wrote Re: Binary question
> I don't know what the correct answer is. Can anyone run this on
> another 32-bit Forth and report the results?
>
> Thanks,
>
> Rick
[1] iForth server 0.92 (console), Jan 31 1999, 12:02:44.
[2] Stuffed iForth at 004393B0 [entry: 0x440000]
[3] Current process priority is 32.
iForth version 1.11, generated 21:08:00, March 12, 2000.
i3 binary, native floating-point, extended precision.
Copyright 1996, 1997, 1998, 1999, 2000 Marcel Hendrix.
FORTH> $CEE1289A $100 / h. $FFCEE129 ok
FORTH> $CEE1289A 2/ 2/ 2/ 2/ 2/ 2/ 2/ 2/ h. $FFCEE128 ok
FORTH> help /
/ "slash" CORE
( n1 n2 -- n3 )
Divide n1 by n2, giving the single-cell quotient n3. An ambiguous
condition exists if n2 is zero. If n1 and n2 differ in sign, the result
returned will be the same as the phrase >R S>D R> SM/REM SWAP DROP .
Note that other implementations of the ANSI standard may return the
phrase >R S>D FM/MOD SWAP DROP .
Win32Forth uses F83-style floored division.
-marcel
.
>From mikek_at_metretek.com Mon May 8 14:29:43 2000
To: sftalk_at_forth.com
Message-Id: <m0000868_at_gerd.forthinc.com>
Date: Mon, 8 May 2000 14:29:43 -0500
From: "Michael Kemper" <mikek_at_metretek.com>
Subject: Re: [sftalk] Binary question
There are options regarding this for FP Math, but I don't see how to do it
with integer math without following Elizabeth's suggestion of redefining the
"/" operator.
I understand why it works the way it does...the question I originally posted
had more to do with the issue of consistency of implementation. I'm not
trying to be as critical as I probably sound.
Thanks for the responses,
Mike
> Rick,
>
> Is there no option to choose symmetric or truncating division? I thought
> I remembered that there is.
>
> Jerry
>
>
>
.
>From sftalk_at_forth.com Mon May 8 13:35:06 2000
To: sftalk_at_forth.com
Message-Id: <m0000869_at_gerd.forthinc.com>
Date: Mon, 8 May 2000 13:35:06 -0500
From: "Gene LeFave" <gene_at_tekdata.com>
Subject: Re: [sftalk] List of objects...
Rick,
I really appreciate your answer, but I have another question. How
does it know to resolve the message number at run time. Doesn't an
object reference W .Name lay down the code to the member at compile
time, or is the code that is compiled always a jump through a table
associated with the objects class?
My guess is that the [objects stuff triggers the compiler to do run
time binding only. What would happen if the object passed is not
derived from WORK?
Gene
Date sent: Mon, 8 May 2000 08:39:13 -0700
From: SF Talk <sftalk_at_forth.com>
To: SF Talk <sftalk_at_forth.com>
Send reply to: SF Talk <sftalk_at_forth.com>
Subject: Re: List of objects...
> Date: Mon, 08 May 2000 08:34:23 -0700
> From: "Rick VanNorman" <rvn_at_forth.com>
> Subject: Re: List of objects...
>
> >From: "Gene LeFave" <gene_at_tekdata.com>
> >Subject: Re: List of objects...
> >
> >Rick,
> >
> >I don't see how the defer: given the address of an object get to the
> >correct run time code.
> >
> >You create a dummy WORK object W in .worker. Yet when you pass it an
> > object of the BOSS class it gets the BOSS version of .name. It
> >seems to me that W .name should always go to WORK .name.
>
> Gene,
>
> There are two mixed up issues here.
>
> First, I flubbed the code. There is no DEFER: needed or desired. The
> code for BOSS should read
>
> WORK SUBCLASS BOSS
>
> VARIABLE BONUS
>
> : .Name .Name ." the great and powerful." ;
>
> END-CLASS
>
> The second is a bit more complicated.
>
> 1. Each object knows what class it belongs to.
> 2. Each class has a linked list of all of its members
> (organized into public, private, protected, etc.).
> 3. Each member is identified by a unique message number. This
> uniqueness is on a per-name basis, not on a per-class basis. So, a
> member named FOOBAR will have the same messge number no matter what
> class it is referenced in. 4. The class WORK has exactly one runtime
> component associated with the member .NAME . 5. The class BOSS, whose
> superclass is WORK, has two components: its own and the one in WORK.
> However, when compiling a reference to an object of class BOSS, the
> only one visible to the compiler is the first one found, i.e., the one
> explicitly defined in BOSS. 6. The reference to the local object W in
> WORKER does a run-time lookup for the member .NAME in the address
> space of whatever class the object belongs to. In the case of the BOSS
> object, the .NAME that is defined in BOSS will be the one found and
> executed by ->
>
> Hope this helps.
>
> Rick
>
>
>
.
Received on Mon May 08 2000 - 11:09:34 PDT
Subscribe to our e-mail list service. It's free for all SwiftForth and SwiftX users!
This archive was generated 07-Feb-2012. Archive updated nightly.