----- Original Message -----
From: "Joe Schell" <[EMAIL PROTECTED]>

>
> First the case can be reduced.
>
> my $base = 16777216;
> my $result;
>
> my $num1 = 1219;
> my $num2 = 219;
> my $num3 = 218;
>
>
> $result = ($num1 % 1000) * 16777216;
> print "number1 = $result\n";
> $result = ($num3 + 1) * 16777216;
> print "number3 = $result\n";
>
> $result = $num2 * 16777216;
> print "number2 = $result\n";
>
> $result = ($num1 % 1000) * $base;
> print "var1 = $result\n";
>
> $result = ($num2 % 1000) * $base;
> print "var2 = $result\n";
>
> The results are
>
> number1 = -620756992
> number3 = 3674210304
> number2 = 3674210304
> var1 = 3674210304
> var2 = 3674210304
>
> The first case is the odd one.
>

Yes - that's the simplification of code that I was seeking. While at work
today, I was wondering whether perhaps this strangeness was associated with
the '%' operator.

> I can guess why this is happening.  The expressions produce numbers that
are
> close to the 32 bit integer representation.  A signed 32 bit integer rolls
> over to a negative number when the number is greater than 2147483647.  And
> the result you have is bigger than that.  Although relatively speaking it
is
> only slightly bigger.

As best I can tell, at this stage, the telling factor is whether it exceeds
the cut-off point. ie I think the extent to which it exceeds that cut-off
point is irrelevant. I was thinking that the "cut-off point" would be 2^32 -
1. You seem to be suggesting that it's 2^31 - 1. You may well be right .....
I haven't quite digested all of this, yet :-)
I'll have a closer look at that.

>
> Perl is supposed to deal with that by converting the number into a
floating
> point representation.  It does that for the expression dealing with the
'+'
> and fails with the '%'.
>
> It is interesting to note that the following code does NOT produce this
> error.
>
> $base = 0x7fffffff;
> $num1 = 5;
> $result = ($num1 % 3) * $base;
> print "hex = $result\n";
>

No - that should not produce the error because you're multiplying by
'$base' - and it's only multiplication by a bare number that's throwing the
error.

Try, instead:
 $num1 = 5;
 $result = ($num1 % 3) * 0x7fffffff;
 print "hex = $result\n";

and you'll still see the same inconsistency.

> And I tried several other small number combinations which failed to
produce
> an overflow either.  I also tried some larger multiplers and the error
still
> occurred.  And since it involves the '%' there is probably some complex
> interaction with expectation of such an expression.
>

Ok - so it seems that there are 3 ingredients that must be present for the
problem to arise:
1) Big numbers - beyond 2^31-1.
2) The  '%' operator.
3) A 'bare number' (for want of a better term).

If any one of those ingredients is missing, then there will be no problem -
though I note that we haven't yet tested the '-' (subtraction) operator.

Zat how you see it ?

> This same result occurs on 5.6.0 on windows and 5.6.1 on Solaris.
>

Interesting to know that ....... something that I'll mention when I
eventually post to perl porters ( as you suggest).

> I would guess that this is a bug.  If it had occurred on only one OS it
> might have been a flaw in the OS or some underlying technology.  Since it
> occurs on both it indicates the error is in the perl code.  Which means it
> should be fixable.
>
> As a work around you can use a temporary variable to hold the expression
>
>    (($_ + $carry) % $div)
>
> And use that in your calculation.
>

Yes - the other workaround is to make sure that there are no 'bare numbers'
involved in the calculations and to *not* 'use constant'. ie as long as all
values are contained in a variable, there seems to be no problem .......
hang on ...... I think I see what you mean ..... with *your* workaround I
could 'use constant' or stick in a bare number ..... yes.

Or, as $Bill demonstrated, one could convert the array elements to BigInt's.
(This is not really an option for me, as speed is of the essence - besides
which it should not be necessary to invoke Math::BigInt where integers less
than 1e16-1 are involved ...... or should that be '1e15-1' ? .... or some
other totally different value ? .... my brain deserts me, yet again :-)
This also leads me to ponder how integers expressed in scientific notation
would behave in the scenario being discussed. I'll have a look at that, too.

> You should also repost this (if you wish using any part of my response) to
> the 'porters' list.  That is more likely to be read by the perl internals
> folks and they can verify if they consider it a bug or not.
>

Thank you, Joe.

One last question - that thing that I've been calling a 'bare number'
............. would a 'constant' be the correct perl terminology for that ?

Cheers,
Rob


_______________________________________________
Perl-Win32-Users mailing list
[EMAIL PROTECTED]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to