> -----Original Message-----
> Behalf Of Sisyphus
>
>
>
> ----- Original Message -----
> From: "Joe Schell" <[EMAIL PROTECTED]>
>
> > > 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 ?
> >
> > Your (1) above is more complex.  The error occurs in the following range
> >
> >    2^31-1 to 2^32-1
> >
> > Where 2^32 works correctly.
> >
>
> Could I prevail upon you one more time to check that ? It's not
> what I get.
> I'm finding that, when multiplying by a numeric literal constant,
> instead of
> getting 2^32 returned to '$result', I'm getting zero.
>

Correct. range should be 2^31-1 to 2^32

> And I find that I'm getting the error if the value being returned to
> '$result' is greater than 2^31-1. That is, the stipulation that the return
> value has to be less than 2^32 - 1 does not apply in my case.
>
> In general, I'm finding that the 'wrong' result is equal to the
> 32 low-order
> bits of the 'correct' result, (with bit 33 being treated as a sign bit).
> That doesn't correlate all that well with what's happening internally, but
> it seems to be one way of deriving the 'wrong' value from the 'correct'
> value.( There's a bit of elaboration on this below.)


I wouldn't get to carried away with trying to unstand the actual parameters
of the problem.  At least not unless you want to dig into the perl source.
And even then I would spend time digging first and only look for odd test
cases if the reason wasn't obvious or to test the fix.  Roll over problems
in C/C++ are a commonly overlooked problem and it seems likely that this is
exactly what it is.

>
> Here's a script you could run for comparison purposes. It doesn't contain
> the conversion to binary - but that's not so important - so long
> as you are
> getting the same decimal values as I am. ( Best to try it with both of the
> values that I've supplied for '$num1'.)
>
> #####################################
> my $base = 167772160; # no longer a power of 2
> my $result;
>
> my $num1 = 1919;
> #my $num1 = 1258;
>
> $result  = ($num1 % 1000) * 167772160;
> print "wrong = $result\n";
>
> $result = ($num1 % 1000) * $base;
> print "right = $result\n";
> #################################
>
> It prints (for $num1 = 1919)
> wrong = -436207616
> right = 154182615040
> The respective binary representations being
>             11100110000000000000000000000000
> 10001111100110000000000000000000000000
> You'll find the first binary number is the binary version of
> 436207616, and
> the minus sign comes about because bit 33 of the 'correct' binary
> number is
> '1'.
>

There won't be a bit 33.  At least not in the way you are representing it.

This is how perl is supposed to work.  'Small' integer numbers in perl are
handle by the underlying OS/platform specific way for handling integer
computations.  When those numbers become 'large' they are converted to a
floating point representation.

On a standard x86 windows box the underlying platform handles 32 bit signed
integers.

   signed 32 bit integer values
      2147483647
      -2147483648

The floating point representation allows for for about 15 digits of
accuracy, which is about 5 more than integers allow.  So when you see a
number like this

    43285217280

It means that perl has started using a floating point representation.

Naturally floating point numbers are represented as bits also, but if I
remember correctly the number takes 8 bytes (64 bits.) And it might be the
case that the first bit is not the sign of the number.  It could be the sign
of the mantissa.

If you search you can probably find the exact range (the fpu of the x86
processor) and layout for a floating point number if you are really
interested.



> It prints (for $num1 = 1258)
> wrong = 335544320
> right = 43285217280
> The respective binary representations being
>         00010100000000000000000000000000
> 101000010100000000000000000000000000
> Here again, the first binary number is the binary representation of
> 335544320, and it stays positive because bit 33 of the 'correct' value is
> '0'.
>
> And to test the case for '2^32' versus '0', try:
> my $t = 1256;
> my $x = ($t % 1000) * 16777216; # ( = 2^32)
> print $x, "\n";
> # prints  0 for me (ignoring the sign bit).
>
> To check what happens when 2^31 is returned:
> my $t = 1002;
> my $x = ($t % 1000) *  1073741824; # ( = 2^31)
> print $x, "\n";
> # prints -2147483648 for me, and I have no explanation
> # for the presence of the minus sign. Since bit 33 of the
> #correct value is
> '0', I would have expected a positive #return value (and hence a correct
> return value).
>
> 2^31 - 1 is prime and will never be returned, and 2^31 - 2 is returned
> correctly, as, presumably are all other values less than 2^31 - 2.
>
> The main thing that I'd like to verify is that you are getting the same
> return values as I did for those pieces of code.
>

Yes.

> Any additional comments (from anyone) are welcome - but it occurs to me
> that, while *I* find this a little intriguing, others (including Joe,
> perhaps) might be finding it downright tedious and bloody boring.
>
> So long as you're finding the same return values as me, then I'm ready to
> post to the porters and see what they have to say about it. I did a search
> of their archive and couldn't find anything on this particular matter.
>

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

Reply via email to