We have
first/0x1p57 - 1 < JAVA{first>>>57} && JAVA{first>>>57} <= first/0x1p57.
Here JAVA{.} stands for Java expression with all its truncations and
wrappings.
Expressions without JAVA{.}are exact mathematical expressions.

JAVA{first>>>57}  <= first/0x1p57 < 1p64/1p57 = 1p7, radix <=
Character.MAX_RADIX = 36, hence
JAVA{(int)(first>>>57)} = JAVA{first>>>57}.
guard = JAVA{radix * (int)(first>>>57)} = radix*JAVA{first>>>57}.

radix*(first/0x1p57 - 1) < guard && guard <= radix*first/0x1p57 .
radix*first/0x1p57 - Character.MAX_RADIX < guard && guard <=
radix*first/0x1p57 .
This means
guard*0xp57 <= first*radix && first*radix < (guard +
Character.MAX_RADIX)*0x1p57
guard*0xp57 <= first*radix + second && first*radix + second < (guard +
Character.MAX_RADIX)*0x1p57 + Character.MAX_RADIX .

Now we shall split by "guard".

When guard >= 128 = 1p7, we have first*first + second >= 1p7 * 1p57 = 1p64
hence overflow always occur in this.

When guard < 128 - Character,MAX_RADIX,  we have
guard + Character.MAX_RADIX <= 127
first*radix + second < 127*0x1p57 + 36 < 0x1p64 , hence overflow doesn't
occur in this.

When 128 - Character.MAX_RADIX <= guard && guard < 128 ,
(128 - Character.MAX_RADIX)*0xp57 <= first*radix + second && first*radix +
second < (127 + Character.MAX_RADIX)*0x1p57 + Character.MAX_RADIX.
0x1p63 < (128 - 36)*0xp57 <= first*radix + second && first*radix + second <
(128 + 36)*1p57 + 36 < 0x1p64 + 0x1p63 .
Hence JAVA{first*radix + second} = (first*radix + second - 0x1p64)
JAVA{result >= 0} = JAVA{first*radix + second >= 0} = (first*radix + second
>= 0x1p64).
Hence overflow is detected correctly in this case too.



On Tue, Dec 24, 2013 at 4:58 AM, Brian Burkhalter <
brian.burkhal...@oracle.com> wrote:

> It looks like this could be rearranged to
>
> long result = first * radix + second;
> int guard = radix * (int) (first >>> 57);
> if (guard >= 128 || (result >= 0 && guard >= 128 - Character.MAX_RADIX)) {
> …
>
> provided reasonable comments were added. I understand the first part of
> this conditional, guard >= 128, but the second part eludes me. Would you
> please explain this part.
>
> BTW this works for the test case in question, of course.
>
> On Dec 21, 2013, at 2:04 AM, Dmitry Nadezhin wrote:
>
> > I can weaken the question:
> > Is there a reason to prefer extra int multiplication to the cache ?
> >
> > long result = first * radix + second;
> > final int GUARD_BIT = 7;
> > int guard = radix * (int) (first >>> (Long.SIZE - GUARD_BIT));
> > if (guard >= (1 << GUARD_BIT) - Character.MAX_RADIX
> >     && (guard >= (1 << GUARD_BIT) || result >= 0)) {
> >  . . .
>
>

Reply via email to