Integer-to-string conversion error solved

Jose E. Marchesi jemarch@gnu.org
Thu Jul 9 18:10:30 GMT 2026


> Good morning, all;
>
> On Thu, Jul 9, 2026 at 9:51 AM Jose E. Marchesi <jemarch@gnu.org> wrote:
>
>>
>> > Thanks, Jose, for the quick response about the current incorrect
>> > string conversions of the most negative integers.
>> >
>> > No, I am certainly not suggesting that ga68 change the implementation
>> > of the Algol 68 MOD operator, which is language defined and must be
>> > standard.
>> >
>> > It is the USE of MOD in integer-to-string conversions that produces an
>> > incorrect string for -(2**(n - 1)), so it is just the conversion
>> > routines that need repair.
>>
>> Yes that's what I was asking.  In our current transput implementation
>> that would be 'subwhole'.
>>
>> I will incorporate your fix in our current transput.
>>
>> Note that Chris Hermansen is working on our new full-fledged transput,
>> based on van Vliet's, which might or might not provide a new
>> implementation of `whole'.  In that case, and if the new implementation
>> uses MOD, we will be careful to use your version so we are compatible
>> with C number printers.
>>
>> > Algol 68 parses integers without a sign, and then only afterwards
>> > applies unary signs.  That is why, as in many programming languages,
>> > there are subterfuges like the C header file, <limits.h>, with code
>> > like this:
>> >
>> >       #define INT_MAX 2147483647
>> >       #define INT_MIN (-INT_MAX - 1)
>> >
>> > A human programmer unfamiliar with details of hardware arithmetic may
>> > well wonder, and complain about, the refusal of the compiler to accept
>> > the constant -2147483648.  My view has always been that compilers
>> > SHOULD accept such constants: all that is needed is digit accumulation
>> > as a negative value, then attaching the sign after all the digits have
>> > been collected: grammar rules, alas, may prevent that helpful
>> > practice.
>>
>> We actually take care in our implementation to support using -2147483647
>> (and similar to other type widths) as an integral denotation:
>>
>>       if (errno == ERANGE
>>           || (NEGATED (p) && (val > max_negative))
>>           || (!NEGATED (p) && (val > max_positive)))
>>         {
>>           a68_moid_format_token m (moid);
>>           a68_error (s, "denotation is too large for %e", &m);
>>         }
>>
>> Note the NEGATED attribute which is stored in the AST node corresponding
>> to the integral denotation.  That is only set if the integral denotation
>> is immediately passed to the unary minus operator.
>>
>> > Two's complement arithmetic is essentially universal today: the CDC
>> > 6x00/7x00 and Univac 11xx systems of the 1960s and 1970s were the last
>> > major CPUs that (I can recall at the moment) had the symmetric one's
>> > complement arithmetic, for which INT_MIN = -INT_MAX, but then also
>> > there is +0 and -0, which complicates comparisons.
>> >
>> > My concern is that output of all possible integers as strings, and
>> > subsequent conversion of those strings back to integers, MUST be
>> > round-trip correct for all possible numbers.
>>
>
> I have a standalone proposed alternative to whole (and subwhole) that at
> least solves the incorrect largest negative problem.  I would like to offer
> it up here for general inspection, evaluation etc before formally proposing
> it.
>
> Also, running it over integers from -1 000 000 to +1 000 000 and sending
> the output to /dev/null, it completes in 1.184s on my desktop, whereas
> using the old whole completes in 2.677s.
>
> Any interest?

You bet :)

Isn't that like proper part of the transput?  We are interested on the
rest of it as well! ^^



More information about the Algol68 mailing list