.
Last update: 1997-05-20
9945-2-96
_____________________________________________________________________________
Topic: bc - precision
Relevant Sections: 4.3.7.1
Defect Report:
-----------------------
Date: Mon, 27 Feb 1995 15:08:40 -0800
From: Phil Nelson <phil@cs.wwu.edu>
To: IEEE Standards Board
Subject: ISO/IEC 9945-2:1993
Topic: precision of functions defined by -l option
Relevant Sections: 4.3.7.1
Dear Standards Board,
I would like to disagree with the following "binding interpretation".
>_____________________________________________________________________________
> ISO/IEC Interpretation reference
> 9945-2-77
>
>_____________________________________________________________________________
>
> Topic: bc - scale
> Relevant Sections: 4.3.7.1
>...
>I would like to an request official, binding interpretation from the
>WG15 concerning the following point in ISO/IEC 9945-2:1993 (POSIX.2).
>
>POSIX.2 Subclause 4.3 specifies the semantics of the "bc" utility. In
>subclause 4.3.7.1, lines 1570-1571 state:
>
> The scale of an invocation of each of these functions shall
> be the scale of the value of the scale register when the
> function is invoked.
>
>The functions referred to are the math functions s(), c(), a(), l(),
>e() and j().
>
>Suppose that bc is invoked with the -l flag, and that the scale is 20.
>What is the value of the expression
>
> scale(a(0))
>
>On the one hand, the sentence quoted above implies that it should be
>20. On the other hand, the value of a(0) is exactly 0, and the scale
>of 0 is 0.
>
>Thank you for your attention to this matter.
>
>Interpretation response:
>-------------------------
>
>
>The specification on lines 1570-1573, page 196 is talking about the scale
>used while computing the value of the arctangent, not about the computed
>arctangent, since arctangent (0) is zero, scale(a(0)) is equivilent to
>scale(0) which is zero.
>
>The standard clearly states the behaviour for bc and scale(), and conforming
>implementations must conform to this.
a) The standard does not give any algorithms on how to compute these
functions.
b) Why should the time of invocation be mentioned IF *ALL* computations
must be done at the same scale.
c) *IF* it is talking about all computations in the function, then the
*RESULT* would have to have the same scale as all the other computations.
therefore scale(a(0)) should be the same scale as when the function
is invoked.
d) scale(x) when (x == 0) IS NOT always zero! Consider the following code:
x = 0.00000
scale(x)
5
(This is the result of /usr/bin/bc on a SUN 4.1 system. Identical
results from GNU bc which was implemented directly from the
POSIX draft standard.)
I say that this IS the correct behavior.
From lines 1405-1407 of 9945-2:1993:
A numeric constant shall be an expression. The scale shall be the
number of digits that follow the radix point in the input
representing the constant, or zero if no radix point appears.
e) By forcing the scale to remain the same value while computing the
functions can produce errors in the results. For example, from the
GNU bc implementation, the following were computed. a is the
original GNU bc arctan function and xa is the same EXCEPT all computations
are done in the scale at the time of call (as per the interpretation)
(Note: this is using a nonstandard feature of GNU bc of multi-character
names. This does not change the computation results.)
a(10000)
1.57069632679522995256
xa(10000)
1.57069632679522995258
scale = 25
a(10000)
1.5706963267952299525626550
xa(10000)
1.5706963267952299525626544
Note: the original "a" is more accurate in the digits returned because
it can change the scale during computation.
The effect is even worse for the ln function (l(x)) as follows.
(Again "l" is the original version and "xl" is the version that does
not adjust scale during computation.)
scale=20
l(1000000)
13.81551055796427410410
xl(1000000)
13.81551055796427409856
scale=30
l(1000000)
13.815510557964274104107948728106
xl(1000000)
13.815510557964274104107948727296
Notice that the original computation returns the exact 20 digits that
are the first 20 of the longer computation. The "new version" that
computes at the orignal scale is wrong in the last 5 digits of the 20.
That is a big error in my opinion.
Quoting again:
>The specification on lines 1570-1573, page 196 is talking about the scale
>used while computing the value of the arctangent, not about the computed
>arctangent, since arctangent (0) is zero, scale(a(0)) is equivilent to
>scale(0) which is zero.
As I understand the above, the function can not change scale
during the computation of the value and be conforming. For the
sine function, this extreme is even worse. In one place in the
GNU bc library code, sine sets scale to zero for a computation.
Changing that to compute at the same scale as everything else yeilds
the following results: (again "s" is the original, "xs" is without
changing scale)
s(1)
.84147098480789650665
xs(1)
-1.00000000000000000002
s(.5)
.47942553860420300027
xs(.5)
1.00000000000000000002
Here is my interpretation of lines 1570-1571:
> The scale of an invocation of each of these functions shall
> be the scale of the value of the scale register when the
> function is invoked.
a) "an invocation" refers only to the result, not how it was computed.
b) "the value of the scale register when the function is invoked" was
used to allow the algorithm to use a larger scale to produce more
accurate results and then return the result with the scale defined
at the start of the algorithm.
c) scale(0) is not always 0. This depends on how the 0 was produced.
For example:
- scale(0.000) should be three.
- scale = 20; scale(0/1) is 20 by definition of / and is the
value 0.00000000000000000000. (lines 1443-1445)
Thank you for considering this.
----------------- End of disagreement --------------------
In working on the above disagreement, I discovered something that I
would like to point out to the committee about output of numbers as
defined in 9945-2 section 4.3.7.1.
Lines 1353 - 1387 define the format and content of output numbers in
bc. It appears to me that there is a major difference between this
specification and tradational bc. That is in the output of the number
zero. (0)
Lines 1355 - 1373 define 3 "paragraphs" on how to output a number.
(1) talks about the minus sign
(2) talks about the integer portion of the digits
(3) talks about the fractional digits.
It appears that (3) is *always* considered. This changes the output
of the number 0.
Traditional output of the number zero was alway the character "0" regardless
of the scale. For example, "scale(0.00000)" prints "5" and "0.00000" prints
"0".
In my reading of lines 1335-1373, the line (1365) "If the numeric value
is zero, bc shall write the character 0." is ONLY part of (2) and does
not stop applying part (3) to the number zero.
Therefore, "0.00000" should print as "0.00000". Is this non-tradational
behavior wanted?
Thank you for looking into these issues.
--Phil Nelson
phil@cs.wwu.edu
(Author of GNU bc.)
Interpretation response:
-------------------------
Upon further consideration, we agree that the response to ISO/IEC Interpretation
#77 is incorrect.
The interpretation on #77 should have been:
(1) the first sentence of the paragraph on page 200 l1570-1573
is poorly worded.
(2) the scale of the result of calling one of the math functions
provided when the -l option is specified, could be interpreted to
be the value of the the scale register at the time the function
is invoked or the scale of 0 (which is 0).
The standard is unclear on this issue, and no conformance distinction can
be made between alternative implementations based on this. This is being
referred to the sponsor.
Rationale:
None
Forwarded to Interpretations group: Mar 4 1995
Proposed resolution circulated: May 16th
Comments due: June 15th
Finalised: June 16th 1995