> -----Original Message-----
> From: Richard Biener <rguent...@suse.de>
> Sent: Friday, March 21, 2025 03:48
> To: Robert Dubner <rdub...@symas.com>
> Cc: Jakub Jelinek <ja...@redhat.com>; gcc-patches@gcc.gnu.org
> Subject: RE: [PATCH][RFC] [cobol] change cbl_field_data_t::etc_t::value
> from _Float128 to tree
>
> On Thu, 20 Mar 2025, Robert Dubner wrote:
>
> > Okay, I managed to figure out a way of getting the debug information
> back
> > into the libgcobol.
> >
> > The addition is done by the routine __gg__add_fixed_phase1()
> >
> > The run-tiome inputs to that routine should be 1 and 55555555555.
> >
> > What's coming through in the patched code are 1 and 55555555554
> >
> > I haven't looked at the compile-time code yet. But I have a nickel
that
> > says somebody is converting "555.55555555" to floating-point, and
> getting
> > an internal value of 555.555555549999999...., and that's getting
> truncated
> > to the internal value of 55555555554
> >
> > I haven't checked for sure, but I suppose I've been counting on the
> > strfromf128 routines to round sensibly. I guess if mpfr can handle
that
> > kind of thing, then we should switch to mpfr. I am not that familiar
> with
> > mpfr.
>
> Note I have not consistently used real_value_truncate to the target
> float128 format - I was debating on whether ->value should be
> aribitrary precision or not. Some real_* functions can take VOIDmode
> (no format, whatever that does exactly), but to build a 'tree' we
> have to use a type (and I've not consistently performed rounding
> or truncation to the format there).
>
> Now a question on COBOL:
>
> 77 var8 PIC 999V9(8) COMP-5
>
> what precision/digits does this specify? When then doing
>
> add 0.00000001 TO var555 giving var8 rounded
>
> what's the precision/digit specification for the literal floating
> point values and how does that or that of var555 or var8
> "promote" or "demote" to a common specification for the arithmetic
> operation?
>
> Does the COBOL standard expect a literal floating point value to
> be represented exactly? Maybe rounding then only applies at the
> "giving var8 rounded" point, forcing the exact value to the
> specification of var8?
Too darned many moving parts.
A COMP-5 on a little-endian machine is a little-endian integer value. On
a big-endian machine, it's a big-endian value. IBM designed it that way
for computational efficiency. My code is not there yet; I have only ever
worked on little-endian machines.
(It won't be hard; at the present time we carry a bit that says, "This
variable is big-endian", and in fact the BINARY storage type (as opposed
to COMP-5) already *is* big-endian, and it works fine. What I haven't
worked out is whether or not the target machine is big-endian; I have no
provision for that.)
PIC 999V9(8) has eleven decimal digits, hence it is stored as a 64-bit
integer. In our data structures, the .capacity is 8 (bytes), the .digits
is 11, and the .rdigits is 8 (for eight digits to the right of the decimal
point.)
One of the things you are finding perplexing is because there has been a
bit of a tug-of-war between me and Jim. I don't use floating-point unless
I have to; I stay in fixed point when operating between fixed point
numbers. Jim thinks I am nuts, as does the COBOL specification, which
describes how all intermediate values should be maintained as
floating-point numbers.
I think *that* is nuts. I categorically refuse to add 1 + 2 to get 3 by
converting the first two values to 128-bit floating point values. So, I
stay in the smallest possible fixed-point values that I can until forced
to go bigger, and I stay in fixed-point until a floating-point value comes
along. This is an issue in things like
COMPUTE X = A + B * C / D
Where A, B, C, and D can be any numerical types.
And so, back to the tug of war: It's evolved, and I no longer can tell
you off the top of my head exactly what I did. Jim wanted to just give me
a floating point number and for me to do everything with that. As I've
indicated, I have had (and did have, during development) too much trouble
with 0.1 not being equal to 0.1 to want deal with that.
So, to answer your question. Without being sure, I am pretty sure that
ADD 0.00000001 TO var555
results in the __gg__add routine in the library being handed a numeric
literal and the variable var555.
And at that time, I look at the var555 variable type. If it is a
fixed-point value (like PIC 99V9999) I hand "0.00000001" from the literal
to one of the routines named "__gg__dirty_to_binary_" that returns the
value 1 and an indication that it saw eight digits to the right of the
decimal point.
And if var555 is a floating-point value, I call __gg__dirty_to_float with
the same string from the literal.
("Dirty" comes from the fact that I use the same routines for coping with
arbitrary user input, where I can't be sure that the string actually is a
clean numerical value.)
This is one of the areas where Jim and I chose to disagree. He stopped
giving me the "0.00000001" string from the source code in favor of giving
me the floating point "value". Unable or unwilling to convince him
otherwise -- he did have his reasons for doing what he did -- I recall
going through the effort of converting the floating point "value" back to
"0.00000001", so that I could handle literals with those _dirty_to
routines, and with less risk of being unable to tell the difference
between a literal "0.1" and a literal "0.099999...99999993"
But memory is blurry; for all I know he went back to giving me what the
programmer put in the source code.
And this, I suspect, is part of the reason for all that string processing
you have been confused about.
There are reasons the front end has over 100,000 lines of code.
>
> Richard.
>
> > > -----Original Message-----
> > > From: Robert Dubner <rdub...@symas.com>
> > > Sent: Thursday, March 20, 2025 17:50
> > > To: Jakub Jelinek <ja...@redhat.com>
> > > Cc: Richard Biener <rguent...@suse.de>; gcc-patches@gcc.gnu.org
> > > Subject: RE: [PATCH][RFC] [cobol] change
> cbl_field_data_t::etc_t::value
> > > from _Float128 to tree
> > >
> > > It's time to slow down a bit and give me a chance to catch up.
> > >
> > > First, all those tests are not arbitrary. I was getting the correct
> > > answers before, and it was not an insignificant effort to get them
> > correct
> > > in the first place.
> > >
> > > If we don't get the same answers, then something isn't the same as
it
> > was
> > > before.
> > >
> > > I need to know what.
> > >
> > > First-prime:
> > >
> > > Also, keep in mind that this is COBOL, where words don't mean what
you
> > > think they mean. Under Rounding, we have
> > >
> > > The following forms of rounding are provided (examples presume an
> > integer
> > > destination):
> > >
> > > -AWAY-FROM-ZERO: Rounding is to the nearest value farther from zero.
> > >
> > > -NEAREST-AWAY-FROM-ZERO: Rounding is to the nearest value. If two
> values
> > > are equally near, the value farther from zero is selected. This mode
> has
> > > historically been associated with the ROUNDED clause in earlier
> versions
> > > of standard COBOL.
> > >
> > > -NEAREST-EVEN: Rounding is to the nearest value. If two values are
> > equally
> > > near, the value whose rightmost digit is even is selected. This mode
> is
> > > sometimes called "Banker's rounding".
> > >
> > > -NEAREST-TOWARD-ZERO: Rounding is to the nearest value. If two
values
> > are
> > > equally near, the value nearer to zero is selected.
> > >
> > > -PROHIBITED: No rounding is performed. If the value cannot be
> > represented
> > > exactly in the desired format, the EC-SIZE-TRUNCATION condition is
set
> > to
> > > exist and the results of the operation are undefined.
> > >
> > > -TOWARD-GREATER: Rounding is toward the nearest value whose
algebraic
> > > value is larger.
> > >
> > > -TOWARD-LESSER: Rounding is toward the nearest value whose algebraic
> > value
> > > is smaller.
> > >
> > > -TRUNCATION: Rounding is to the nearest value that is nearer to zero
> > than
> > > the algebraic value. This mode has historically been associated with
> the
> > > absence of the ROUNDED clause as well as for the formation of
> > intermediate
> > > results in the prior COBOL standard.
> > >
> > > Any of those can be set as the default.
> > >
> > > Second, I just tried to debug the way I have been debugging for
years
> --
> > > and I can't.
> > >
> > > I wanted to check that the attempt to add 0.00000001 to 555.55555555
> was
> > > actually adding those two numbers. This wasn't a rounding problem.
> > Both
> > > of those numbers have eight decimal places. So, internally, 1 is
> > supposed
> > > to be added to a 64-bit integer value 55555555555 to get 55555555556
> > >
> > > I am suspicious that the 0.00000001 is becoming zero, which would
> result
> > > in the 555.55555555 being unchanged.
> > >
> > > To do an initial check of this, I tried to trap at
> > __gg__add_fixed_phase1
> > >
> > > But libgcobol.so has no debug info. So, somehow, the way I used to
> > cause
> > > it to be "-ggdb -O0" has gotten lost. I need it back.
> > >
> > > What I have been doing, lo these many months, is compiling after
doing
> > > this ../configure
> > >
> > > CFLAGS="-ggdb -O0" \
> > > CXXFLAGS="-ggdb -O0" \
> > > CFLAGS_FOR_BUILD="-ggdb" \
> > > CXXFLAGS_FOR_BUILD="-ggdb" \
> > > LIBCFLAGS_FOR_BUILD="-ggdb" \
> > > LIBCXXFLAGS_FOR_BUILD="-ggdb" \
> > > CFLAGS_FOR_TARGET="-ggdb -O0" \
> > > CXXFLAGS_FOR_TARGET="-ggdb -O0" \
> > > LIBCFLAGS_FOR_TARGET="-ggdb -O0" \
> > > LIBCXXFLAGS_FOR_TARGET="-ggdb -O0" \
> > > ../configure \
> > > --with-pkgversion="$PKGVERSION" \
> > > --enable-languages=c,c++,cobol \
> > > --prefix=/usr/local/gcobol \
> > > --with-gcc-major-version-only \
> > > --program-suffix=-$MAJOR_VERSION \
> > > --enable-shared \
> > > --enable-linker-build-id \
> > > --without-included-gettext \
> > > --enable-threads=posix \
> > > --disable-bootstrap \
> > > --enable-clocale=gnu \
> > > --enable-libstdcxx-debug \
> > > --enable-libstdcxx-time=yes \
> > > --with-default-libstdcxx-abi=new \
> > > --enable-gnu-unique-object \
> > > --disable-vtable-verify \
> > > --enable-plugin \
> > > --enable-default-pie \
> > > --with-system-zlib \
> > > --with-target-system-zlib=auto \
> > > --disable-werror \
> > > --disable-cet \
> > > $arch_options \
> > > --disable-multilib \
> > > --without-cuda-driver \
> > > --enable-checking \
> > > --build=$arch-linux-gnu \
> > > --host=$arch-linux-gnu \
> > > --target=$arch-linux-gnu \
> > > --with-build-config=bootstrap-lto-lean \
> > > --enable-link-mutex --without-isl
> > >
> > > And, no, I don't know what much of that means. I cloned it from the
> > > Ubuntu "gcc -v" description of their configuration.
> > >
> > > But I do know that one of those flag settings used to control the
> build
> > of
> > > the library. But now the library isn't being built with debug_info,
> and
> > I
> > > need it to be.
> > >
> > > I'll start looking, but any help would be appreciated.
> > >
> > > > -----Original Message-----
> > > > From: Jakub Jelinek <ja...@redhat.com>
> > > > Sent: Thursday, March 20, 2025 17:07
> > > > To: Robert Dubner <rdub...@symas.com>
> > > > Cc: Richard Biener <rguent...@suse.de>; gcc-patches@gcc.gnu.org
> > > > Subject: Re: [PATCH][RFC] [cobol] change
> > cbl_field_data_t::etc_t::value
> > > > from _Float128 to tree
> > > >
> > > > On Thu, Mar 20, 2025 at 03:30:30PM -0500, Robert Dubner wrote:
> > > > > Let me find one inky-dink example. Talk amongst
yourselves...here
> > we
> > > > go.
> > > > >
> > > > > identification division.
> > > > > program-id. prog.
> > > > > data division.
> > > > > working-storage section.
> > > > > 77 var8 PIC 999V9(8) COMP-5 .
> > > > > 77 var555 PIC 999V99999999 COMP-5 VALUE 555.55555555.
> > > > > procedure division.
> > > > > move 555.55555555 to var8
> > > > > add 0.00000001 TO var555 giving var8 rounded
> > > > > if var8 not equal to 555.55555556 display var8 " should
be
> > > > > 555.55555556".
> > > > > end program prog.
> > > > >
> > > > > With your patches, the output is
> > > > >
> > > > > 555.55555555 should be 555.55555556
> > > >
> > > > Thanks.
> > > > Now, the code certainly could try to do the rounding of the last
> > digits
> > > > based on the remaining digits in the string that are being
> discarded,
> > > > if followed by 0-4, don't change anything, if followed by 6-9,
> > increase
> > > > last digit, if followed by 5 and any non-zero digit, increase too,
> if
> > > > followed
> > > > by 5 and all zeros, round to even.
> > > > But I'm afraid it can have double rounding, when round_to_decimal
> > rounds
> > > > for the precision 33 printing something e.g. with
> 49999999999999999999
> > > at
> > > > the end to 500000000000 and this second rounding again.
> > > > So I really think we should go to mpfr, I can implement it
tomorrow
> > > unless
> > > > Richi wants to do that.
> > > >
> > > > Jakub
> >
> >
>
> --
> Richard Biener <rguent...@suse.de>
> SUSE Software Solutions Germany GmbH,
> Frankenstrasse 146, 90461 Nuernberg, Germany;
> GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG
Nuernberg)