Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

IBM2435I on ROUND(x,-3) by RULES(NOLAXSCALE)

34 views
Skip to first unread message

Robin Vowels

unread,
Dec 7, 2011, 7:33:03 AM12/7/11
to
SKY@AXA

Nov 17
Hello
We got the IBM2435I Message (Scale factor is less than 0) by Rounding
with negative values.(PL/I V4R1 on z/OS)

But in the PL/I Documentation, rounding with negative values are
documented (valid):
If n is zero or negative, rounding occurs at the (1-n)th digit to the
left of the point.

so why do we get this (error) message ?

Yes, we can get the IBM2435I Message down to Warning, but then, this
happens for all other Statements, where this message is reasonable.

Code Example:

SKY0165: PROC OPTIONS(MAIN);

DCL RESULT FIXED DEC(18,06);
DCL TEST FIXED DEC(18,06);
TEST = 12_345.678;

RESULT = ROUND(TEST,-3);
PUT SKIP LIST('ROUND WITH -3 = '!!RESULT);

END SKY0165;

Thank you, Patrick
___________________

Looks like a bug.

test: procedure options (main);
declare x fixed (15,5);

x = round(1234567.89, -3);
put skip data (x);
end;

gives

X= 1235000.00000;

John W Kennedy

unread,
Dec 7, 2011, 10:30:42 AM12/7/11
to
Next time, look up the message in the messages manual.

You have RULES(NOLAXSCALE) in effect.

--
John W Kennedy
"You can, if you wish, class all science-fiction together; but it is
about as perceptive as classing the works of Ballantyne, Conrad and W.
W. Jacobs together as the 'sea-story' and then criticizing _that_."
-- C. S. Lewis. "An Experiment in Criticism"

Robin Vowels

unread,
Dec 22, 2011, 2:37:50 AM12/22/11
to
Hi,
I'm puzzled about the following conversion via ROUND.
Any ideas?
_________________

test: procedure options (main);

declare d fixed (10,5);

d = '1234.567';

put skip data (d);

d = round('1234.567', 2);

put skip data (d);

end test;

Output:

D= 1234.56700;
D= 1234.00000;

glen herrmannsfeldt

unread,
Dec 22, 2011, 3:01:32 AM12/22/11
to
Robin Vowels <robin....@gmail.com> wrote:

> I'm puzzled about the following conversion via ROUND.
> Any ideas?

> test: procedure options (main);
> declare d fixed (10,5);
> d = '1234.567';

I haven't thought about this for a while. I believe the character
string is first converted to floating point. It is, at least,
if you take the square root of a CHAR variable.

Is there some reason not to use a decimal constant?

Not that I am at all against using CHAR in numeric expressions.

> put skip data (d);
> d = round('1234.567', 2);
> put skip data (d);
> end test;

> Output:

> D= 1234.56700;
> D= 1234.00000;

-- glen

Robin Vowels

unread,
Dec 22, 2011, 6:33:05 AM12/22/11
to
On Dec 22, 7:01 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> Robin Vowels <robin.vow...@gmail.com> wrote:
> >   I'm puzzled about the following conversion via ROUND.
> >   Any ideas?
> > test: procedure options (main);
> >   declare d fixed (10,5);
> >   d = '1234.567';
>
> I haven't thought about this for a while.  I believe the character
> string is first converted to floating point.  It is, at least,
> if you take the square root of a CHAR variable.
>
> Is there some reason not to use a decimal constant?

I'm interested in seeing the case when the argument is taken from a
character string (which could be the case when a number is taken
from an input device.

Peter Flass

unread,
Dec 22, 2011, 8:05:52 AM12/22/11
to
You don't say what compiler and platform, but possible it's due to the
conversion of the character constant.

<quote>
The constant has base, scale, mode, and precision attributes. It
converts to the attributes of the target when they are independent of
the source attributes, as in the case of assignment. See the specific
target types of coded arithmetic data using the attributes of the
constant as the source.

If an intermediate result is necessary, as in evaluation of an
operational expression, the attributes of the intermediate result are
the same as if a decimal fixed-point value of precision (N,0) had
appeared in place of the string. (This allows the compiler to generate
code to handle all cases, regardless of the attributes of the contained
constant.) Consequently, any fractional portion of the constant might be
lost.
</quote>

http://publibfp.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/c1472851/5.6?DT=20110908013800

glen herrmannsfeldt

unread,
Dec 22, 2011, 8:56:29 AM12/22/11
to
Peter Flass <Peter...@yahoo.com> wrote:
> You don't say what compiler and platform, but possible it's due to the
> conversion of the character constant.

> <quote>
> The constant has base, scale, mode, and precision attributes. It
> converts to the attributes of the target when they are independent of
> the source attributes, as in the case of assignment. See the specific
> target types of coded arithmetic data using the attributes of the
> constant as the source.

> If an intermediate result is necessary, as in evaluation of an
> operational expression, the attributes of the intermediate result are
> the same as if a decimal fixed-point value of precision (N,0) had
> appeared in place of the string. (This allows the compiler to generate
> code to handle all cases, regardless of the attributes of the contained
> constant.) Consequently, any fractional portion of the constant might be
> lost.
> </quote>

I was remembering 36 years ago when I used a CHAR variable as the
argument of SQRT. I do remember that the square root was done in double
precision floating point, but I didn't remember how it got there.
So, after converting to fixed dec(N,0), in the case of SQRT, it then
converts to floating point, there being (or wasn't 36 years ago) a
FIXED DEC version of SQRT.

> http://publibfp.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/c1472851/5.6?DT=20110908013800

Useful to keep the conversion table nearby when doing things like this.

-- glen

Robin Vowels

unread,
Dec 22, 2011, 10:05:21 AM12/22/11
to
On Dec 23, 12:05 am, Peter Flass <Peter_Fl...@Yahoo.com> wrote:
> You don't say what compiler and platform, but possible it's due to the
> conversion of the character constant.
>
> <quote>
> The constant has base, scale, mode, and precision attributes. It
> converts to the attributes of the target when they are independent of
> the source attributes, as in the case of assignment. See the specific
> target types of coded arithmetic data using the attributes of the
> constant as the source.
>
> If an intermediate result is necessary, as in evaluation of an
> operational expression, the attributes of the intermediate result are
> the same as if a decimal fixed-point value of precision (N,0) had
> appeared in place of the string. (This allows the compiler to generate
> code to handle all cases, regardless of the attributes of the contained
> constant.) Consequently, any fractional portion of the constant might be
> lost.
> </quote>

Interesting, but I don't see that applying in this case.
The implied conversion is to FIXED DECIMAL (6, 2)
[or FIXED DEC (M, 2) in the general case with a string variable],
by reason of the arguments to ROUND.

glen herrmannsfeldt

unread,
Dec 22, 2011, 3:09:09 PM12/22/11
to
Robin Vowels <robin....@gmail.com> wrote:

(snip, someone wrote)

>> If an intermediate result is necessary, as in evaluation of an
>> operational expression, the attributes of the intermediate result are
>> the same as if a decimal fixed-point value of precision (N,0) had
>> appeared in place of the string. (This allows the compiler to generate
>> code to handle all cases, regardless of the attributes of the contained
>> constant.) Consequently, any fractional portion of the constant might be
>> lost.
>> </quote>

> Interesting, but I don't see that applying in this case.
> The implied conversion is to FIXED DECIMAL (6, 2)
> [or FIXED DEC (M, 2) in the general case with a string variable],
> by reason of the arguments to ROUND.

In the case of an assignment to a numeric variable, the compiler
uses the attributes of that variable. (That already is pretty
unusual. Normally the right hand side is evaluated based on
its attributes, then converted as appropriate.)

In the case of an expression, as an operand of an operator or function
argument, the compiler does not make any assumptions about what
attributes the result should have. You know that you want
FIXED DEC(M,2), but the compiler doesn't look at the function arguments.

Possibly in the case of the functions name after attributes, like
FLOAT or DECIMAL it would, but even that I don't see in the
above quote.

-- glen

Peter Flass

unread,
Dec 22, 2011, 3:36:24 PM12/22/11
to
On 12/22/2011 8:56 AM, glen herrmannsfeldt wrote:
>
> Useful to keep the conversion table nearby when doing things like this.
>

I've got that page of the manual bookmarked.

Peter Flass

unread,
Dec 22, 2011, 3:39:11 PM12/22/11
to
On 12/22/2011 3:09 PM, glen herrmannsfeldt wrote:
>
> Possibly in the case of the functions name after attributes, like
> FLOAT or DECIMAL it would, but even that I don't see in the
> above quote.
>

I was going to say "of course it does," but now I'm thinking probably
not since conversions from CHARACTER are a special case. All I have now
is PL/I for OS/2 (just installed it today, by coincidence). It would be
interesting to see someone test this on a mainframe.

James J. Weinkam

unread,
Dec 22, 2011, 3:46:47 PM12/22/11
to
ROUND has nothing to do with your problem. You are up against one of the unfortunate aspects of the conversion rules.
Here is the relevant section from the on line LRM for Personal PL/I for OS/2:

Target: Coded Arithmetic

Source:

...

CHARACTER
The source string must represent a valid arithmetic constant or complex expression; otherwise, the CONVERSION condition
is raised. The constant can be preceded by a sign and can be surrounded by blanks. The constant cannot contain blanks
between the sign and the constant, or between the end of the real part and the sign preceding the imaginary part of a
complex expression.

The constant has base, scale, mode, and precision attributes. It converts to the attributes of the target when they are
independent of the source attributes, as in the case of assignment. See the specific target types of coded arithmetic
data using the attributes of the constant as the source.

If an intermediate result is necessary, as in evaluation of an operational expression, the attributes of the
intermediate result are the same as if a decimal fixed-point value of precision (M,0)* had appeared in place of the
string. (This allows the compiler to generate code to handle all cases, regardless of the attributes of the contained
constant.) Consequently, any fractional portion of the constant might be lost. See the specific target types of coded
arithmetic data using FIXED DECIMAL as the source.

It is possible that during the initial conversion of the character data item to an intermediate fixed decimal number,
the value might exceed the default size of the intermediate result. If this occurs, the SIZE condition is raised if it
is enabled.

If a character string representing a complex number is assigned to a real target, the complex part of the string is not
checked for valid arithmetic characters and CONVERSION cannot be raised, since only the real part of the string is
assigned to the target.

A null string gives the value zero; [a string of blanks is invalid.]**

* M is the implementation maximum precision. The (M,0) is missing from the Personal PL/I LRM and all recent LRMs that I
have copies of. This is an obvious misprint. The Optimizer manual had (15,0); for the Optimizer, M=15.

** This phrase is not present in the Optimizer manual.

Robin Vowels

unread,
Dec 22, 2011, 6:32:29 PM12/22/11
to
On Dec 23, 12:56 am, glen herrmannsfeldt <g...@ugcs.caltech.edu>
wrote:

> I was remembering 36 years ago when I used a CHAR variable as the
> argument of SQRT.  I do remember that the square root was done in double
> precision floating point, but I didn't remember how it got there.
> So, after converting to fixed dec(N,0), in the case of SQRT,

No it doesn't. It converts to FIXED DEC (M, n), preserving any
fraction.

> it then
> converts to floating point, there being (or wasn't 36 years ago) a
> FIXED DEC version of SQRT.

SQRT has always converted to FLOAT.

Robin Vowels

unread,
Dec 22, 2011, 6:43:49 PM12/22/11
to
On Dec 23, 7:46 am, "James J. Weinkam" <j...@cs.sfu.ca> wrote:

> ROUND has nothing to do with your problem. You are up against one of the unfortunate aspects of the conversion rules.

I think that it does, for the same thing does not occur with
other BIFs, like SQRT.

Robin Vowels

unread,
Dec 22, 2011, 6:40:35 PM12/22/11
to
On Dec 23, 7:09 am, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> Robin Vowels <robin.vow...@gmail.com> wrote:
>
> (snip, someone wrote)
>
> >> If an intermediate result is necessary, as in evaluation of an
> >> operational expression, the attributes of the intermediate result are
> >> the same as if a decimal fixed-point value of precision (N,0) had
> >> appeared in place of the string. (This allows the compiler to generate
> >> code to handle all cases, regardless of the attributes of the contained
> >> constant.) Consequently, any fractional portion of the constant might be
> >> lost.
> >> </quote>
> > Interesting, but I don't see that applying in this case.
> > The implied conversion is to FIXED DECIMAL (6, 2)
> > [or FIXED DEC (M, 2) in the general case with a string variable],
> > by reason of the arguments to ROUND.
>
> In the case of an assignment to a numeric variable, the compiler
> uses the attributes of that variable.  (That already is pretty
> unusual.  Normally the right hand side is evaluated based on
> its attributes, then converted as appropriate.)
>
> In the case of an expression, as an operand of an operator or function
> argument, the compiler does not make any assumptions about what
> attributes the result should have.

For an argument that is an expression, the compiler does
not make "assumptions" about the attributes of the result.
The attributes are entirely defined by the rules for conversion
(if required) of the operands and operators.
Then, that result is converted (if needed) to the attributes of the
corresponding parameter.

>  You know that you want
> FIXED DEC(M,2), but the compiler doesn't look at the function arguments.

????

> Possibly in the case of the functions name after attributes, like
> FLOAT or DECIMAL it would, but even that I don't see in the
> above quote.

?????

Robin Vowels

unread,
Dec 22, 2011, 6:46:42 PM12/22/11
to
On Dec 23, 7:39 am, Peter Flass <Peter_Fl...@Yahoo.com> wrote:

> I was going to say "of course it does," but now I'm thinking probably
> not since conversions from CHARACTER are a special case.  All I have now
> is PL/I for OS/2

... and Ironspring PL/I. What does that do?

Robin Vowels

unread,
Dec 22, 2011, 7:14:57 PM12/22/11
to
On Dec 23, 7:46 am, "James J. Weinkam" <j...@cs.sfu.ca> wrote:
I see no reason that some character constants need to be converted to
precision (M, 0).

A decimal constant in a character string has clear unequivocal
attributes. A routine to convert to some coded form is
definitely possible. And conversion to some other form
(as the result of assignment or conversion to the attributes
of a parameter, etc) ic clear-cut.

I can see that in the early days (1960s) that there would have been
a need to keep code relatively compact, and by restricting the range
of conversions possible [by forcing to (M, 0)] a means of minimising
the object code is achieved.

However, there does not seem to be any need for that now.
And if one wishes, the character string can be converted
properly, by using the form get string (s) list (z);
by means of which the conversion is fully and correctly carried out.
The use of this conversion method [via get string] implies that
all the conversion routines are available anyway.

glen herrmannsfeldt

unread,
Dec 22, 2011, 10:11:29 PM12/22/11
to
Robin Vowels <robin....@gmail.com> wrote:

(snip, someone wrote)
>> ROUND has nothing to do with your problem. You are up against
>> one of the unfortunate aspects of the conversion rules.

(snip)
>> The source string must represent a valid arithmetic constant
>> or complex expression; otherwise, the CONVERSION condition
>> is raised. The constant can be preceded by a sign and can be
>> surrounded by blanks.

(snip)
>> The constant has base, scale, mode, and precision attributes.
>> It converts to the attributes of the target when they are
>> independent of the source attributes, as in the case of assignment.
>> See the specific target types of coded arithmetic
>> data using the attributes of the constant as the source.


(snip)

> I see no reason that some character constants need to be converted to
> precision (M, 0).

> A decimal constant in a character string has clear unequivocal
> attributes. A routine to convert to some coded form is
> definitely possible. And conversion to some other form
> (as the result of assignment or conversion to the attributes
> of a parameter, etc) ic clear-cut.

The compiler doesn't look inside a character string. If you want
it to use the appropriate attributes, don't use a CHAR constant.

The conversion rules are the same as for a CHAR variable.

> I can see that in the early days (1960s) that there would have been
> a need to keep code relatively compact, and by restricting the range
> of conversions possible [by forcing to (M, 0)] a means of minimising
> the object code is achieved.

Well, they could have converted to FLOAT DEC which would not have
truncated the fraction, but the rules posted indicate FIXED DEC.

> However, there does not seem to be any need for that now.
> And if one wishes, the character string can be converted
> properly, by using the form get string (s) list (z);

In this case, it knows the attributes of the target variable,
as it also does for assignment. In the case of a function, the
attributes of the assignment target don't propagate back to the
argument. At compile time the attributes of the conversion need
to be known.

> by means of which the conversion is fully and correctly carried out.
> The use of this conversion method [via get string] implies that
> all the conversion routines are available anyway.

There are plenty of languages that allow the attributes of a variable
to change depending on its current value. PL/I isn't one of them.

-- glen

James J. Weinkam

unread,
Dec 22, 2011, 11:02:29 PM12/22/11
to
You have a point. I had never noticed this before. It seems inconsistent.

James J. Weinkam

unread,
Dec 22, 2011, 11:08:03 PM12/22/11
to
Robin Vowels wrote:
>
> I see no reason that some character constants need to be converted to
> precision (M, 0).

I agree with you that there doesnt seem to be a compelling reason, nevertheless that's what all the manuals say. On the
ohter hand you example of SQRT shows that the statement in the manual is not always applied.

>
> A decimal constant in a character string has clear unequivocal
> attributes. A routine to convert to some coded form is
> definitely possible. And conversion to some other form
> (as the result of assignment or conversion to the attributes
> of a parameter, etc) ic clear-cut.
>
> I can see that in the early days (1960s) that there would have been
> a need to keep code relatively compact, and by restricting the range
> of conversions possible [by forcing to (M, 0)] a means of minimising
> the object code is achieved.
>
> However, there does not seem to be any need for that now.
> And if one wishes, the character string can be converted
> properly, by using the form get string (s) list (z);
> by means of which the conversion is fully and correctly carried out.
> The use of this conversion method [via get string] implies that
> all the conversion routines are available anyway.

I learned years ago never to use a character variable in an arithmetic expression. I always convert the character
variable to the desired arithmetic attributes using either GET STRING or simple assignment.

glen herrmannsfeldt

unread,
Dec 23, 2011, 1:12:25 AM12/23/11
to
James J. Weinkam <j...@cs.sfu.ca> wrote:

(snip)
> I learned years ago never to use a character variable in an arithmetic
> expression. I always convert the character variable to the desired
> arithmetic attributes using either GET STRING or simple assignment.

I probably already said this a few times, but I did this one
in high school. I don't think I would in a real program, though.

dcl (a,b,c,d) char(100);

a=' 1';
b=' 100'
c='1';
do d=a to b by c;
put skip list(d, sqrt(d));
end;

I believe that is close, 35 years later. The blanks in the
constants were worked through a few tries. The comparison
in the do loop is done as a character compare, not a numerical
compare.

I also did:

dcl x complex fixed bin(31);
x=0;
do imag(x)= 1 to 100;
put skip list(x, sqrt(x));
end;

note that imag() is both a function and pseudo-variable as
used by the do statement.

-- glen

Peter Flass

unread,
Dec 23, 2011, 7:32:09 AM12/23/11
to
On 12/22/2011 3:46 PM, James J. Weinkam wrote:
> Robin Vowels wrote:
>> Hi,
>> I'm puzzled about the following conversion via ROUND.
>> Any ideas?
>> _________________
>>
>> test: procedure options (main);
>>
>> declare d fixed (10,5);
>>
>> d = '1234.567';
>>
>> put skip data (d);
>>
>> d = round('1234.567', 2);
>>
>> put skip data (d);
>>
>> end test;
>>
>> Output:
>>
>> D= 1234.56700;
>> D= 1234.00000;
>
> ROUND has nothing to do with your problem. You are up against one of the
> unfortunate aspects of the conversion rules. Here is the relevant
> section from the on line LRM for Personal PL/I for OS/2:
>
...

I can understand why it has to be this way, though I wish it were
otherwise. For a constant the compiler could determine precision,
scale, and mode, but for character variables it has no way to tell.
The precision and scale have to be known to generate code, unless you're
willing to accept everything being done by a subroutine call.

Peter Flass

unread,
Dec 23, 2011, 7:34:07 AM12/23/11
to
That's why I have the manual page bookmarked. I always try to follow
what it says explicitly, unless I run into cases where the manual is
vague or silent.

Peter Flass

unread,
Dec 23, 2011, 7:38:51 AM12/23/11
to
On 12/22/2011 7:14 PM, Robin Vowels wrote:
>
> I see no reason that some character constants need to be converted to
> precision (M, 0).
>
> A decimal constant in a character string has clear unequivocal
> attributes. A routine to convert to some coded form is
> definitely possible. And conversion to some other form
> (as the result of assignment or conversion to the attributes
> of a parameter, etc) ic clear-cut.
>
> I can see that in the early days (1960s) that there would have been
> a need to keep code relatively compact, and by restricting the range
> of conversions possible [by forcing to (M, 0)] a means of minimising
> the object code is achieved.
>
> However, there does not seem to be any need for that now.
> And if one wishes, the character string can be converted
> properly, by using the form get string (s) list (z);
> by means of which the conversion is fully and correctly carried out.
> The use of this conversion method [via get string] implies that
> all the conversion routines are available anyway.

I think it's more a question of consistency. If you substitute a
character variable for a constant the program would operate differently
and the language designers and compiler writers were trying to avoid
surprises.

a = '12.34';

would not yield the same result as:

DCL b CHAR(5) INIT( '12.34' );
a = b;

Robin Vowels

unread,
Dec 23, 2011, 9:24:53 AM12/23/11
to
As I pointed out in a previous post, the assignements to 'a'
deliver exactly the same result.

test: proc options (main);
declare a fixed decimal (4,2);

a = '12.34';
put skip data (a);

DCL b CHAR(5) INIT( '12.34' );
a = b;
put skip data (a);

end test;

Output:

A= 12.34;
A= 12.34;

See also next post for additional examples.

Robin Vowels

unread,
Dec 23, 2011, 9:27:10 AM12/23/11
to
Here are examples of various conversions and their results:

test: procedure options (main);

declare d fixed (10,5); declare s character (20);

d = '1234.567';

put skip data (d);

d = round('1234.567', 2);

put skip data (d);

put skip list ( round('1234.567', 2) );

put skip list ( sqrt('9.9'), sqrt(9.90000000000000e0) );

s = '1234.567';
get string ('1234.567') list (d);
put skip data (d);
get string (s) list (d);
put skip data (d);
s = 0.1111111;
put skip list (sin(s), sin('0.1111111') );

end test;

Output:

D= 1234.56700;
D= 1234.00000;
1234.00
3.14642654451045E+0000 3.14642654451045E+0000
D= 1234.56700;
D= 1234.56700;
1.10882617467358E-0001 1.10882617467358E-0001

John W Kennedy

unread,
Dec 23, 2011, 10:10:39 AM12/23/11
to
On 2011-12-22 23:32:29 +0000, Robin Vowels said:

> On Dec 23, 12:56 am, glen herrmannsfeldt <g...@ugcs.caltech.edu>
> wrote:
>
>> I was remembering 36 years ago when I used a CHAR variable as the
>> argument of SQRT.  I do remember that the square root was done in double
>> precision floating point, but I didn't remember how it got there.
>> So, after converting to fixed dec(N,0), in the case of SQRT,
>
> No it doesn't. It converts to FIXED DEC (M, n), preserving any
> fraction.

No it doesn't. You have already seen the quote from the manual earlier
in this thread.

"If an intermediate result is necessary, as in evaluation of an
operational expression, the attributes of the intermediate result are
the same as if a decimal fixed-point value of precision (N,0) had
appeared in place of the string. (This allows the compiler to generate
code to handle all cases, regardless of the attributes of the contained
constant.) Consequently, any fractional portion of the constant might
be lost. See the specific target types of coded arithmetic data using
FIXED DECIMAL as the source."

(And what you are saying here isn't even theoretically possible to
begin with. You're describing a value that is FIXED and FLOAT at the
same time.)

The unvarnished truth is this: allowing character strings to
participate in arithmetic was a design error in the original language,
one of many errors that seemed like a good idea at the time. Careful
programmers never use it; if they /must/ convert a character string to
a numeric value, they use PICTURE or PICSPEC, if possible, or some form
of GET STRING if not.

John W Kennedy

unread,
Dec 23, 2011, 10:23:53 AM12/23/11
to
On 2011-12-23 00:14:57 +0000, Robin Vowels said:
> I see no reason that some character constants need to be converted to
> precision (M, 0).

Because they have to be converted to FIXED (M, something). What do you
suppose "FIXED" /means/.

> A decimal constant in a character string has clear unequivocal
> attributes.

PL/I has a long history of treating constants as though they were
variables with the same content.
X = ROUND('123.4567');
is exactly the same as
DCL T CHAR(8) INIT ('123.4567'); X = ROUND(T);

> I can see that in the early days (1960s) that there would have been
> a need to keep code relatively compact, and by restricting the range
> of conversions possible [by forcing to (M, 0)] a means of minimising
> the object code is achieved.
>
> However, there does not seem to be any need for that now.
> And if one wishes, the character string can be converted
> properly, by using the form get string (s) list (z);
> by means of which the conversion is fully and correctly carried out.
> The use of this conversion method [via get string] implies that
> all the conversion routines are available anyway.

Oh, by all means let's make a radical change to semantics that entails
making the value of a constant different from the value of a lexically
equal variable; that's /exactly/ what an already dying language needs.

I have a better solution: don't do such an asinine thing as taking the
ROUND of a character string in the first place.

John W Kennedy

unread,
Dec 23, 2011, 10:31:34 AM12/23/11
to
It's more than that. By definition, a value with a run-time scale is FLOAT.

glen herrmannsfeldt

unread,
Dec 23, 2011, 3:17:19 PM12/23/11
to
John W Kennedy <jwk...@attglobal.net> wrote:

(snip)
> (And what you are saying here isn't even theoretically possible to
> begin with. You're describing a value that is FIXED and FLOAT at the
> same time.)

It is theoretically possible, and sometimes done in interpreted
languages, but pretty much never in compiled languages.

Awk, for example, keeps both a character string and floating point
value for each variable, and will convert between them and save the
converted value. (I believe it saves them, but I believe that is
mostly an optimization. It could convert on each use.)

Many interpreted languages dynamically change a variable's
type depending on the last assignment.

-- glen

John W Kennedy

unread,
Dec 23, 2011, 9:24:57 PM12/23/11
to
Character and floating-point is easy-peasy. Character and
floating-point and fixed-point is a contradiction in terms. Why do you
think almost no languages do fixed-point, apart from pure integers?
It's intrinsically hard. COBOL, PL/I, Ada, and RPG are the only ones I
can think of that even tried, and COBOL botched it utterly (until the
latest revision), PL/I got it only half-right, and RPG simplified its
way around the problem by only allowing single-operator statements. Ada
manages it well, but only by compelling the programmer to explicitly
specify all intermediate precisions (and by establishing integer as a
tertium quid so that it doesn't need the special rules).

glen herrmannsfeldt

unread,
Dec 24, 2011, 1:51:17 AM12/24/11
to
John W Kennedy <jwk...@attglobal.net> wrote:

(snip, I wrote)
>> Many interpreted languages dynamically change a variable's
>> type depending on the last assignment.

> Character and floating-point is easy-peasy. Character and
> floating-point and fixed-point is a contradiction in terms. Why do you
> think almost no languages do fixed-point, apart from pure integers?

Well, that is a different question. As far as dynamic typing, all
you need to do is add bits that indicate the current type and code
to test them at run time. It is a lot slower, so compiled languages
tend not to do it. (None that I know, but it is possible.)

> It's intrinsically hard. COBOL, PL/I, Ada, and RPG are the only ones I
> can think of that even tried, and COBOL botched it utterly (until the
> latest revision), PL/I got it only half-right, and RPG simplified its
> way around the problem by only allowing single-operator statements. Ada
> manages it well, but only by compelling the programmer to explicitly
> specify all intermediate precisions (and by establishing integer as a
> tertium quid so that it doesn't need the special rules).

Another choice is rational, where the result is the ratio of two
integers. My TI-92 calculator does that. It also gives a pi symbol
when appropriate, and ln(integer) when that is an appropriate
exact result.

If you want a decimal approximation, there is an operator for that.

I wondered some time ago about a floating point format with one
bit that indicates to multily by pi. That would allow for exact
multiples of pi to be returned when appropriate. The hardware would
use that and generate an approximate pi when an operation that
couldn't keep an exact answer was done.

-- glen

Robin Vowels

unread,
Dec 24, 2011, 5:14:56 AM12/24/11
to
On Dec 24, 2:10 am, John W Kennedy <jwke...@attglobal.net> wrote:
> On 2011-12-22 23:32:29 +0000, Robin Vowels said:
>
> > On Dec 23, 12:56 am, glen herrmannsfeldt <g...@ugcs.caltech.edu>
> > wrote:
>
> >> I was remembering 36 years ago when I used a CHAR variable as the
> >> argument of SQRT.  I do remember that the square root was done in double
> >> precision floating point, but I didn't remember how it got there.
> >> So, after converting to fixed dec(N,0), in the case of SQRT,
>
> > No it doesn't. It converts to FIXED DEC (M, n), preserving any
> > fraction.
>
> No it doesn't. You have already seen the quote from the manual earlier
> in this thread.

Yu're wrong.
Go look at the immediately preceding post to yours,
where the results are shown [here repeated]:

>put skip list ( sqrt('9.9'), sqrt(9.90000000000000e0) );

>Output:

> 3.14642654451045E+0000 3.14642654451045E+0000

What do you see?

John W Kennedy

unread,
Dec 24, 2011, 9:37:26 AM12/24/11
to
On 2011-12-24 06:51:17 +0000, glen herrmannsfeldt said:

> John W Kennedy <jwk...@attglobal.net> wrote:
>
> (snip, I wrote)
>>> Many interpreted languages dynamically change a variable's
>>> type depending on the last assignment.
>
>> Character and floating-point is easy-peasy. Character and
>> floating-point and fixed-point is a contradiction in terms. Why do you
>> think almost no languages do fixed-point, apart from pure integers?
>
> Well, that is a different question. As far as dynamic typing, all
> you need to do is add bits that indicate the current type and code
> to test them at run time.

Better to use OO techniques, as Ruby does. But if you mix scaled
fixed-point in, it still leaves the intermediate-precision problem
unanswered.

> It is a lot slower, so compiled languages
> tend not to do it. (None that I know, but it is possible.)

For a machine-language compiler, it's pointless. Of course, there are
bitcode compilers, both stored (like Java) and immediate (like Perl).

>> It's intrinsically hard. COBOL, PL/I, Ada, and RPG are the only ones I
>> can think of that even tried, and COBOL botched it utterly (until the
>> latest revision), PL/I got it only half-right, and RPG simplified its
>> way around the problem by only allowing single-operator statements. Ada
>> manages it well, but only by compelling the programmer to explicitly
>> specify all intermediate precisions (and by establishing integer as a
>> tertium quid so that it doesn't need the special rules).
>
> Another choice is rational, where the result is the ratio of two
> integers. My TI-92 calculator does that. It also gives a pi symbol
> when appropriate, and ln(integer) when that is an appropriate
> exact result.

> If you want a decimal approximation, there is an operator for that.

Some languages and libraries allow it. But it's not used commonly
because most real-world problems don't really need it. In finance,
rounding was already the established algorithm long before computers,
and in science and engineering, most numbers are approximate, anyway.

> I wondered some time ago about a floating point format with one
> bit that indicates to multily by pi. That would allow for exact
> multiples of pi to be returned when appropriate. The hardware would
> use that and generate an approximate pi when an operation that
> couldn't keep an exact answer was done.

Again, it's a solution looking for a problem. Indeed, what with the
lost bit, I'm not sure it would even do theoretical good.

John W Kennedy

unread,
Dec 24, 2011, 10:18:45 AM12/24/11
to
I see an idiot who thinks that when a compiler doesn't do what the
manual says, the manual must be wrong.

Peter Flass

unread,
Dec 24, 2011, 12:45:02 PM12/24/11
to
On 12/24/2011 10:18 AM, John W Kennedy wrote:
> On 2011-12-24 10:14:56 +0000, Robin Vowels said:
>
>> On Dec 24, 2:10 am, John W Kennedy <jwke...@attglobal.net> wrote:
>>> On 2011-12-22 23:32:29 +0000, Robin Vowels said:
>>>
>>>> On Dec 23, 12:56 am, glen herrmannsfeldt <g...@ugcs.caltech.edu>
>>>> wrote:
>>>
>>>>> I was remembering 36 years ago when I used a CHAR variable as the
>>>>> argument of SQRT. I do remember that the square root was done in
>>>>> double
>>>>> precision floating point, but I didn't remember how it got there.
>>>>> So, after converting to fixed dec(N,0), in the case of SQRT,
>>>
>>>> No it doesn't. It converts to FIXED DEC (M, n), preserving any
>>>> fraction.
>>>
>>> No it doesn't. You have already seen the quote from the manual earlier
>>> in this thread.
>>
>> Yu're wrong.
>> Go look at the immediately preceding post to yours,
>> where the results are shown [here repeated]:
>>
>>> put skip list ( sqrt('9.9'), sqrt(9.90000000000000e0) );
>>
>>> Output:
>>
>>> 3.14642654451045E+0000 3.14642654451045E+0000
>>
>> What do you see?
>
> I see an idiot who thinks that when a compiler doesn't do what the
> manual says, the manual must be wrong.
>

There are several kinds of "wrong". Either way something is wrong.

Peter Flass

unread,
Dec 24, 2011, 12:47:45 PM12/24/11
to
The hardware could do this. Intel FPUs generate pi when necessary, they
could easily generate n*pi, but I'm not sure it would be more accurate
than just multiplying.

As for rational, Interpress made a lot of use of rational numbers, not a
bad idea considering that (I believe) Altos didn't have hardware
floating point.


glen herrmannsfeldt

unread,
Dec 24, 2011, 2:51:23 PM12/24/11
to
John W Kennedy <jwk...@attglobal.net> wrote:

(snip, I wrote)
>> Another choice is rational, where the result is the ratio of two
>> integers. My TI-92 calculator does that. It also gives a pi symbol
>> when appropriate, and ln(integer) when that is an appropriate
>> exact result.

>> If you want a decimal approximation, there is an operator for that.

> Some languages and libraries allow it. But it's not used commonly
> because most real-world problems don't really need it. In finance,
> rounding was already the established algorithm long before computers,
> and in science and engineering, most numbers are approximate, anyway.

The TI-84 will find a fraction that represents the decimal answer,
which is nice. I don't believe, though, that it finds fractions or
multiples of pi. It is nice for definite integrals and inverse trig
functions to give the appropriate multiple of pi.

-- glen

Shmuel Metz

unread,
Dec 24, 2011, 5:22:28 PM12/24/11
to
In <jd3sp5$lmi$1...@speranza.aioe.org>, on 12/24/2011
at 06:51 AM, glen herrmannsfeldt <g...@ugcs.caltech.edu> said:

>I wondered some time ago about a floating point format with one bit
>that indicates to multily by pi.

What about other important constants that appear in Mathematics, e.g.,
e, and in Physics, e.g., h? I don't see taking up a bit for just one
of those to be reasonable.

--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>

Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spam...@library.lspace.org

glen herrmannsfeldt

unread,
Dec 24, 2011, 7:24:30 PM12/24/11
to
Shmuel (Seymour J.) Metz <spam...@library.lspace.org.invalid> wrote:
> In <jd3sp5$lmi$1...@speranza.aioe.org>, on 12/24/2011
> at 06:51 AM, glen herrmannsfeldt <g...@ugcs.caltech.edu> said:

>>I wondered some time ago about a floating point format with one bit
>>that indicates to multily by pi.

> What about other important constants that appear in Mathematics, e.g.,
> e, and in Physics, e.g., h? I don't see taking up a bit for just one
> of those to be reasonable.

Well, for constants with units, the problem is slightly different.

You could have a storage format that includes the full dimensionality
of quantities and would convert to different unit systems as needed.

Still, even with only dimensionless constants one could have e,
ln(2), ln(10), sqrt(pi), and various powers of such constants.

The thought was that the first power of pi came up enough more often
than the rest that it would be the first choice.

The PL/I degree based trigonometric functions reduces somewhat the
need for pi floating around, though.

-- glen

John W Kennedy

unread,
Dec 24, 2011, 8:29:10 PM12/24/11
to
On 2011-12-24 22:22:28 +0000, Shmuel (Seymour J.) Metz said:

> In <jd3sp5$lmi$1...@speranza.aioe.org>, on 12/24/2011
> at 06:51 AM, glen herrmannsfeldt <g...@ugcs.caltech.edu> said:
>
>> I wondered some time ago about a floating point format with one bit
>> that indicates to multily by pi.
>
> What about other important constants that appear in Mathematics, e.g.,
> e, and in Physics, e.g., h? I don't see taking up a bit for just one
> of those to be reasonable.

h is only known to about ten digits anyway. c, the fine-structure
constant, Big G, and so forth are not materially better.

James J. Weinkam

unread,
Dec 25, 2011, 12:48:55 AM12/25/11
to
John W Kennedy wrote:
> On 2011-12-24 10:14:56 +0000, Robin Vowels said:
>
>> On Dec 24, 2:10 am, John W Kennedy <jwke...@attglobal.net> wrote:
>>> On 2011-12-22 23:32:29 +0000, Robin Vowels said:
>>>
>>>> On Dec 23, 12:56 am, glen herrmannsfeldt <g...@ugcs.caltech.edu>
>>>> wrote:
>>>
>>>>> I was remembering 36 years ago when I used a CHAR variable as the
>>>>> argument of SQRT. I do remember that the square root was done in double
>>>>> precision floating point, but I didn't remember how it got there.
>>>>> So, after converting to fixed dec(N,0), in the case of SQRT,
>>>
>>>> No it doesn't. It converts to FIXED DEC (M, n), preserving any
>>>> fraction.
>>>
>>> No it doesn't. You have already seen the quote from the manual earlier
>>> in this thread.
>>
>> Yu're wrong.
>> Go look at the immediately preceding post to yours,
>> where the results are shown [here repeated]:
>>
>>> put skip list ( sqrt('9.9'), sqrt(9.90000000000000e0) );
>>
>>> Output:
>>
>>> 3.14642654451045E+0000 3.14642654451045E+0000
>>
>> What do you see?
>
> I see an idiot who thinks that when a compiler doesn't do what the manual says, the manual must be wrong.
>
Gentlemen, please. Instead of calling each other names, let's see if we can't sort this out.

A couple of days ago, I said that the application of the sentence in the manual that is the crux or the matter here
seemed inconsistent. After thinking it over for a couple of days, I believe I can explain the apparent anomaly.

Let us first consider the relevant passage in the manual concerning the conversion of character strings used in expressions:

If an intermediate result is necessary, as in evaluation of an operational expression, the attributes of the
intermediate result are the same as if a decimal fixed-point value of precision (M,0) had appeared in place of the
string. (This allows the compiler to generate code to handle all cases, regardless of the attributes of the contained
constant.) Consequently, any fractional portion of the constant might be lost. See the specific target types of coded
arithmetic data using FIXED DECIMAL as the source.

Note the following:

1. The attributes of the intermediate result are the same as if ...

2. ... any fractional portion of the constant *might* be lost.

3. See the specific target types ... using FIXED DECIMAL as source.

Note also that the functions in question in this discussion are generic in the sense that the behavior of the function
and the attributes of the returned result depend on the attributes of the argument(s).

Now consider the definition of the SQRT builtin function:

SQRT(x) returns a floating-point value that is an approximation of the positive square root of the expression x. It has
the base, mode, and precision of x. If x is real, it must not be less than zero.

From this it is evident that the scale of both the result and the actual argument is float. Therefore the value of the
argument is converted to FLOAT DECIMAL. Moreover the source to target rules for this case state:

FIXED DECIMAL (p1,q1)
The precision of the result is p2=p1. The exponent indicates any fractional part of the value.

In other words, FIXED DECIMAL(M,) would be converted to FLOAT DECIMAL(M), and in the actual conversion process, any
fractional part of the constant expressed in character form would influence the exponent of the converted result and the
fractional digits would not actually be lost.

In short no actual inconsistency.

Finally consider the definition of the ROUND builtin function:

ROUND(x,n) returns the value of the real expression x rounded at a digit specified by n. The result has the mode, base,
and scale of x. If x is negative, the absolute value is rounded and the sign is restored.

n Optionally-signed integer. It specifies the digit at which rounding is to occur. n must conform to the limits of
scaling-factors for FIXED data. If n is greater than 0, rounding occurs at the (n)th digit to the right of the point. If
n is zero or negative, rounding occurs at the (1-n)th digit to the left of the point.

The precision of a fixed-point result is given in the following example where (p,q) is the precision of x, and N is the
maximum number of digits allowed:

(max(1,min(p-q+1+n,N)),n)


Thus, n specifies the scaling factor of the result.

In this case, the mode of the result is REAL, the base is DECIMAL, and the scale id FIXED. A DECIMAL FIXED(M,0) value
would be "converted" to DECIMAL FIXED(M,0). When the actual conversion of the character value happens any fractional
digits will be lost since none are available in the target.

Again no actual inconsistency.



Robin Vowels

unread,
Dec 25, 2011, 6:44:13 AM12/25/11
to
On Dec 25, 2:18 am, John W Kennedy <jwke...@attglobal.net> wrote:
> On 2011-12-24 10:14:56 +0000, Robin Vowels said:
>
>
>
>
>
> > On Dec 24, 2:10 am, John W Kennedy <jwke...@attglobal.net> wrote:
> >> On 2011-12-22 23:32:29 +0000, Robin Vowels said:
>
> >>> On Dec 23, 12:56 am, glen herrmannsfeldt <g...@ugcs.caltech.edu>
> >>> wrote:
>
> >>>> I was remembering 36 years ago when I used a CHAR variable as the
> >>>> argument of SQRT.  I do remember that the square root was done in double
> >>>> precision floating point, but I didn't remember how it got there.
> >>>> So, after converting to fixed dec(N,0), in the case of SQRT,
>
> >>> No it doesn't. It converts to FIXED DEC (M, n), preserving any
> >>> fraction.
>
> >> No it doesn't. You have already seen the quote from the manual earlier
> >> in this thread.
>
> > Yu're wrong.
> > Go look at the immediately preceding post to yours,
> > where the results are shown [here repeated]:
>
> >> put skip list ( sqrt('9.9'),  sqrt(9.90000000000000e0) );
>
> >> Output:
>
> >> 3.14642654451045E+0000  3.14642654451045E+0000
>
> > What do you see?
>
> I see an idiot who thinks that when a compiler doesn't do what the
> manual says, the manual must be wrong.

Let's see who the idiot is.
In this case, the compiler does, in point of fact,
do what the manual says.
Look under "Source to target rules".
Then look under the immediate sub-heading target "Coded arithmetic".
Then look under the sub-sub-heading "CHARACTER".
You will then read "The constant has base, scale, mode, and precision
attributes. It converts to the attributes of the target ... as in the
case of assignment."
So, then, who has read but fails to comprehend the manual?

John W Kennedy

unread,
Dec 25, 2011, 7:42:36 PM12/25/11
to
That's (N,0). The distinction is critical; N means, as elsewhere, the
maximum allowed value for p. In the case of DECIMAL, that is 15 or 31
depending on LIMITS(FIXEDDEC(n)). (There is no doubt of this; older
manuals say "(15,0)" instead of "(N,0)".)

> Note the following:
>
> 1. The attributes of the intermediate result are the same as if ...
>
> 2. ... any fractional portion of the constant *might* be lost.
>
> 3. See the specific target types ... using FIXED DECIMAL as source.
>
> Note also that the functions in question in this discussion are generic
> in the sense that the behavior of the function and the attributes of
> the returned result depend on the attributes of the argument(s).
>
> Now consider the definition of the SQRT builtin function:
>
> SQRT(x) returns a floating-point value that is an approximation of the
> positive square root of the expression x. It has the base, mode, and
> precision of x. If x is real, it must not be less than zero.
>
> From this it is evident that the scale of both the result and the
> actual argument is float. Therefore the value of the argument is
> converted to FLOAT DECIMAL. Moreover the source to target rules for
> this case state:
>
> FIXED DECIMAL (p1,q1)
> The precision of the result is p2=p1. The exponent indicates any
> fractional part of the value.
>
> In other words, FIXED DECIMAL(M,) would be converted to FLOAT
> DECIMAL(M), and in the actual conversion process, any fractional part
> of the constant expressed in character form would influence the
> exponent of the converted result and the fractional digits would not
> actually be lost.
>
> In short no actual inconsistency.

What the manual actually says is that the character value is converted
to FIXED DECIMAL(N,0), period. It may be that it is not meant to say
that, but it goes back some time -- definitely to V2R3M0. Not all the
way to (F), though, where the wording is entirely different, and
specifies, in fact, that the result is FIXED DECIMAL(5,0)! But it also,
unlike the later versions, allows for direct conversion to FLOAT
instead.

It seems that there is a disconnect between the manual and the
compiler. I suspect that the compiler's logic is based on a mixture of
the (F) manual and the Optimizer/Enterprise manual (with a choice
between FIXED and FLOAT, but with FIXED DECIMAL(N,0) instead of FIXED
DECIMAL(5,0)). I also believe that this is the best compromise, and the
compiler should be left as-is. I would recommend, therefore, that
someone (I don't have the standing) send in a Reader's Comment Form.

> Finally consider the definition of the ROUND builtin function:
>
> ROUND(x,n) returns the value of the real expression x rounded at a
> digit specified by n. The result has the mode, base, and scale of x. If
> x is negative, the absolute value is rounded and the sign is restored.
>
> n Optionally-signed integer. It specifies the digit at which rounding
> is to occur. n must conform to the limits of scaling-factors for FIXED
> data. If n is greater than 0, rounding occurs at the (n)th digit to the
> right of the point. If n is zero or negative, rounding occurs at the
> (1-n)th digit to the left of the point.
>
> The precision of a fixed-point result is given in the following example
> where (p,q) is the precision of x, and N is the maximum number of
> digits allowed:
>
> (max(1,min(p-q+1+n,N)),n)
>
>
> Thus, n specifies the scaling factor of the result.
>
> In this case, the mode of the result is REAL, the base is DECIMAL, and
> the scale id FIXED. A DECIMAL FIXED(M,0) value would be "converted" to
> DECIMAL FIXED(M,0). When the actual conversion of the character value
> happens any fractional digits will be lost since none are available in
> the target.
>
> Again no actual inconsistency.

For this case, I think the compiler and the manual are in agreement.

John W Kennedy

unread,
Dec 25, 2011, 8:02:07 PM12/25/11
to
The key sentence has been posted multiple times in this thread, and yet
you refuse even to acknowledge that it's there.

This has been going on for over a decade now. It is clear that you are
simply incapable of ever admitting that you are wrong about anything.
Everything you like can't just be good; it has to be the ne plus ultra,
and all doubt is forbidden. For God's sake, seek professional help.

Peter Flass

unread,
Dec 26, 2011, 9:42:42 AM12/26/11
to
On 12/25/2011 7:42 PM, John W Kennedy wrote:
[snip]
>
> What the manual actually says is that the character value is converted
> to FIXED DECIMAL(N,0), period. It may be that it is not meant to say
> that, but it goes back some time -- definitely to V2R3M0. Not all the
> way to (F), though, where the wording is entirely different, and
> specifies, in fact, that the result is FIXED DECIMAL(5,0)! But it also,
> unlike the later versions, allows for direct conversion to FLOAT instead.
>
> It seems that there is a disconnect between the manual and the compiler.
> I suspect that the compiler's logic is based on a mixture of the (F)
> manual and the Optimizer/Enterprise manual (with a choice between FIXED
> and FLOAT, but with FIXED DECIMAL(N,0) instead of FIXED DECIMAL(5,0)). I
> also believe that this is the best compromise, and the compiler should
> be left as-is. I would recommend, therefore, that someone (I don't have
> the standing) send in a Reader's Comment Form.

I assume at this point everyone is talking about the Enterprise
compiler, but it would be nice to say, and also specify the release.

Enterprise has more incompatibilities with prior versions than earlier
compilers did. [I couldn't figure out how to word this so it made sense,
but I hope the meaning is clear] This makes sense since it was a
completely new compiler, written from scratch. Unfortunately it also
seems to have been written by people who didn't pay particularly close
attention to the manual, and also most of the manual was carried over
without change. Maybe IBM didn't want to pay an editor?

James J. Weinkam

unread,
Dec 27, 2011, 6:48:36 PM12/27/11
to
John W Kennedy wrote:
>
> That's (N,0). The distinction is critical; N means, as elsewhere, the maximum allowed value for p. In the case of
> DECIMAL, that is 15 or 31 depending on LIMITS(FIXEDDEC(n)). (There is no doubt of this; older manuals say "(15,0)"
> instead of "(N,0)".)

The Personal PL/I LRM as well as several others that I have pdf's of do not actually have the (N,0) in the text (an
obvious misprint). The only LRM that I have that actually has something there is my old optimizer manual, and it says
(15,0) as you point out. I was using M to mean the implementation maximum precision. If you prefer N, fine.

...

>
> What the manual actually says is that the character value is converted to FIXED DECIMAL(N,0), period.

No, that's not what is says. What it actually says is:

"... the attributes of the intermediate result are the same as if a decimal fixed-point value of precision (N,0) had
appeared in place of the string. (This allows the compiler to generate code to handle all cases, regardless of the
attributes of the contained constant.) Consequently, any fractional portion of the constant might be lost. See the
specific target types of coded arithmetic data using FIXED DECIMAL as the source."


In other words, once you know the attributes of the target (intermediate result), you have to look elsewhere to see how
the conversion is actually carried out in any specific case.

Note the word might and the last sentence of the quotation.

In the situation at hand, the attributes of the intermediate result are FLOAT DECIMAL(M), what a FIXED DECIMAL(M,0)
value would be converted to. At run time the string itself may contain the character representation of any valid coded
arithmetic value; whatever it is it will be converted to FLOAT DECIMAL(M) in the usual way.

John W Kennedy

unread,
Dec 27, 2011, 10:12:53 PM12/27/11
to
But once you have the intermediate result, the fraction is already
gone. It can't appear again from nowhere unless the meaning of
"intermediate result" is changed from what it has always meant. It
makes much more sense to me that the actual compiler is doing what the
F compiler was originally documented as doing -- only going to FIXED
when FIXED is wanted, and going to FLOAT otherwise, the only difference
from F, then, is that it goes to FIXED DECIMAL(N,0) instead of an
arbitrary FIXED DECIMAL(5,0). (Just in case you forget, FIXED
DECIMAL(5,0) is the traditional default for variables declared FIXED
DECIMAL with no precision at all.) It means the least difference from F
(and a generally benign one), and comes about as close as this
ill-conceived feature allows to obeying the Rule of Least Astonishment
-- and it is easy to imagine how a correction made 40 years ago in the
manual text could have gone wrong and never been caught.

I make the "might" as an orphan reference to both the FLOAT case and
the no-intermediate-result case.

Peter Flass

unread,
Dec 28, 2011, 7:44:54 AM12/28/11
to
Nonsense, it's an IBM conspiracy to prevent people from cloning their
compiler ;-) I do wish they'd fix the manual, but I suppose it would
require a combination of knowledge and ability that no one has any more.

James J. Weinkam

unread,
Dec 28, 2011, 5:21:59 PM12/28/11
to
John W Kennedy wrote:
> On 2011-12-27 23:48:36 +0000, James J. Weinkam said:

...

>>>
>>> What the manual actually says is that the character value is converted to FIXED DECIMAL(N,0), period.
>>
>> No, that's not what is says. What it actually says is:
>>
>> "... the attributes of the intermediate result are the same as if a decimal fixed-point value of precision (N,0) had
>> appeared in place of the string. (This allows the compiler to generate code to handle all cases, regardless of the
>> attributes of the contained constant.) Consequently, any fractional portion of the constant might be lost. See the
>> specific target types of coded arithmetic data using FIXED DECIMAL as the source."
>>
>>
>> In other words, once you know the attributes of the target (intermediate result), you have to look elsewhere to see
>> how the conversion is actually carried out in any specific case.
>>
>> Note the word might and the last sentence of the quotation.
>>
>> In the situation at hand, the attributes of the intermediate result are FLOAT DECIMAL(M), what a FIXED DECIMAL(M,0)
>> value would be converted to. At run time the string itself may contain the character representation of any valid coded
>> arithmetic value; whatever it is it will be converted to FLOAT DECIMAL(M) in the usual way.
>
> But once you have the intermediate result, the fraction is already gone.

Nowhere does the manual say the the string is first converted to FIXED DECIMAL(N,0).

The key point is that at compile time, all that the (possibly contrary to fact) assumption of FIXED DECIMAL(N,0) is used
for is to determine the base, scale, mode, and precision that the value of the string will be converted to at run time.

For each operation in an arithmetic expression, whether it be a prefix operation, an infix operation, or a builtin or
user defined function, the compiler needs to know the base, scale, mode, and precision of each operand. With this
information, the compiler uses a well defined set of rules based on the operation to be performed and the known
attributes of all of the operands to determine what if any operand conversions are required and what operation to
perform or entry point to invoke (in the case of generic functions). These rules also determine the exact base, scale,
mode, and precision of the result.

This need is met in every case except the one under discussion, namely when an operand is a character string. The
compiler knows for certain that the string must be converted to some coded arithmetic data type, but what type should
that be? In order to proceed, the compiler generates code to convert the string to whatever coded arithmetic data type
it would have converted a FIXED DECIMAL(N,0) variable or constant to. Only in the case where a FIXED DECIMAL(N,0) value
would have required no conversion is the string actually converted to those attributes.


...

> I make the "might" as an orphan reference to both the FLOAT case and the no-intermediate-result case.
>

I am not sure exactly what you mean by this statement. I interpret the might to mean that while any fractional digits in
the string will be lost in some cases, some or all of them will survive in other cases. The same applies to the
imaginary part of a complex value.

John W Kennedy

unread,
Dec 28, 2011, 9:07:59 PM12/28/11
to
But that is what "intermediate result" /means/.

Shmuel Metz

unread,
Dec 29, 2011, 11:03:38 AM12/29/11
to
In <jd5qfu$lgm$1...@speranza.aioe.org>, on 12/25/2011
at 12:24 AM, glen herrmannsfeldt <g...@ugcs.caltech.edu> said:

>The thought was that the first power of pi came up enough more often
>than the rest that it would be the first choice.

My first choice would be to not give up a bit of precision at all.

glen herrmannsfeldt

unread,
Dec 29, 2011, 2:25:19 PM12/29/11
to
Shmuel (Seymour J.) Metz <spam...@library.lspace.org.invalid> wrote:
> In <jd5qfu$lgm$1...@speranza.aioe.org>, on 12/25/2011
> at 12:24 AM, glen herrmannsfeldt <g...@ugcs.caltech.edu> said:

>>The thought was that the first power of pi came up enough more often
>>than the rest that it would be the first choice.

> My first choice would be to not give up a bit of precision at all.

Not so long after I wrote that one, I had the idea that it could be done
with the representations that are now denormals. Personally, I don't
like denormals very much. They get you a tiny fraction of an additional
bit of exponent range, and potentially a lot of additional work or logic
to compute.

There are enough bits now being used for denormals to represent many
different multiples of pi that tend to come up, along with some other
dimensionless constants if that was desired.

-- glen
0 new messages