From: Gib Bogle on
orz wrote:
> On Jul 30, 10:14 pm, Gib Bogle <g.bo...(a)auckland.no.spam.ac.nz> wrote:
>> orz wrote:
>>> Yes. Sorry. I was reading backwards from your last post and ended up
>>> missing the point. And getting confused on the sign.
>>> Anyway, the issue is that Georges code uses a different definition of
>>> sign than your implementation of it - his code is actually correct if
>>> sign(x) is 1 if x is positive and 0 if x is negative. Since your sign
>>> function returns -1 on negative, using it produces the wrong
>>> results.
>>> side note: The incorrect results produced that way at a appear to have
>>> vaguely similar statistical properties as the original C codes output,
>>> passing and failing the same tests that the original C code does in my
>>> brief tests.
>> Interesting, who would have guessed that there is a language in which sign(-1) = 0.
>
> I have to correct myself for swapping 0 and 1 *again*. And I'm not
> even dyslexic, so far as I know.
>
> His code assumed sign returned 1 on negative, and 0 otherwise, as in a
> simple unsigned 31 bit rightshift. The exact opposite of what I
> said.

I tried your suggestion, replacing the sign() function with one based on your
rule. It doesn't work, i.e. it gives results different from the C code.
From: orz on
On Aug 10, 11:02 am, Gib Bogle <g.bo...(a)auckland.no.spam.ac.nz> wrote:
> orz wrote:
> > On Jul 30, 10:14 pm, Gib Bogle <g.bo...(a)auckland.no.spam.ac.nz> wrote:
> >> orz wrote:
> >>> Yes.  Sorry.  I was reading backwards from your last post and ended up
> >>> missing the point.  And getting confused on the sign.
> >>> Anyway, the issue is that Georges code uses a different definition of
> >>> sign than your implementation of it - his code is actually correct if
> >>> sign(x) is 1 if x is positive and 0 if x is negative.  Since your sign
> >>> function returns -1 on negative, using it produces the wrong
> >>> results.
> >>> side note: The incorrect results produced that way at a appear to have
> >>> vaguely similar statistical properties as the original C codes output,
> >>> passing and failing the same tests that the original C code does in my
> >>> brief tests.
> >> Interesting, who would have guessed that there is a language in which sign(-1) = 0.
>
> > I have to correct myself for swapping 0 and 1 *again*.  And I'm not
> > even dyslexic, so far as I know.
>
> > His code assumed sign returned 1 on negative, and 0 otherwise, as in a
> > simple unsigned 31 bit rightshift.  The exact opposite of what I
> > said.
>
> I tried your suggestion, replacing the sign() function with one based on your
> rule.  It doesn't work, i.e. it gives results different from the C code..

If I made yet another mistake on that then I'm going to throw
something.

It produced identical results for me when I tried it in C using this
code:

typedef unsigned int Uint32;
Uint32 sign(Uint32 value) {return value>>31;}
Uint32 index, carry, data[4691];
Uint32 mwc4691() {
index = (index < 4690) ? index + 1 : 0;
Uint32 x = data[index];
Uint32 t = (x << 13) + carry + x;
if (sign((x<<13)+carry) == sign(x))
carry = sign(x) + (x>>19);
else carry = 1 - sign(t) + (x>>19);
data[index] = t;
return t;
}

I think the only difference between that and the algorithm he
expressed in pseudocode is that I added parentheses on the first left-
shift (he was apparently assuming higher precedence on the leftshift
operator than C uses). Maybe that's why you're getting different
results?
From: Gib Bogle on
orz wrote:

> If I made yet another mistake on that then I'm going to throw
> something.
>
> It produced identical results for me when I tried it in C using this
> code:
>
> typedef unsigned int Uint32;
> Uint32 sign(Uint32 value) {return value>>31;}
> Uint32 index, carry, data[4691];
> Uint32 mwc4691() {
> index = (index < 4690) ? index + 1 : 0;
> Uint32 x = data[index];
> Uint32 t = (x << 13) + carry + x;
> if (sign((x<<13)+carry) == sign(x))
> carry = sign(x) + (x>>19);
> else carry = 1 - sign(t) + (x>>19);
> data[index] = t;
> return t;
> }
>
> I think the only difference between that and the algorithm he
> expressed in pseudocode is that I added parentheses on the first left-
> shift (he was apparently assuming higher precedence on the leftshift
> operator than C uses). Maybe that's why you're getting different
> results?

You do realize that there's no unsigned integer type in Fortran? I don't think
there's much point in trying to predict what the Fortran code does without using
a Fortran compiler. Don't you have one?
From: Dann Corbit on
In article <i3ssd1$be8$1(a)speranza.aioe.org>,
g.bogle(a)auckland.no.spam.ac.nz says...
>
> orz wrote:
>
> > If I made yet another mistake on that then I'm going to throw
> > something.
> >
> > It produced identical results for me when I tried it in C using this
> > code:
> >
> > typedef unsigned int Uint32;
> > Uint32 sign(Uint32 value) {return value>>31;}
> > Uint32 index, carry, data[4691];
> > Uint32 mwc4691() {
> > index = (index < 4690) ? index + 1 : 0;
> > Uint32 x = data[index];
> > Uint32 t = (x << 13) + carry + x;
> > if (sign((x<<13)+carry) == sign(x))
> > carry = sign(x) + (x>>19);
> > else carry = 1 - sign(t) + (x>>19);
> > data[index] = t;
> > return t;
> > }
> >
> > I think the only difference between that and the algorithm he
> > expressed in pseudocode is that I added parentheses on the first left-
> > shift (he was apparently assuming higher precedence on the leftshift
> > operator than C uses). Maybe that's why you're getting different
> > results?
>
> You do realize that there's no unsigned integer type in Fortran? I don't think
> there's much point in trying to predict what the Fortran code does without using
> a Fortran compiler. Don't you have one?

Maybe he is using Sun's Fortran 95 compiler.

From:
http://docs.sun.com/source/819-0492/4_f95.html

"4.5 Unsigned Integers
The Fortran 95 compiler accepts a new data type, UNSIGNED, as an
extension to the language. Four KIND parameter values are accepted with
UNSIGNED: 1, 2, 4, and 8, corresponding to 1-, 2-, 4-, and 8-byte
unsigned integers, respectively.

The form of an unsigned integer constant is a digit-string followed by
the upper or lower case letter U, optionally followed by an underscore
and kind parameter. The following examples show the maximum values for
unsigned integer constants:


255u_1
65535u_2
4294967295U_4
18446744073709551615U_8



Expressed without a kind parameter (12345U), the default is the same as
for default integer. This is U_4 but can be changed by the -xtypemap
option, which will change the kind type for default unsigned integers.

Declare an unsigned integer variable or array with the UNSIGNED type
specifier:


UNSIGNED U
UNSIGNED(KIND=2) :: A
UNSIGNED*8 :: B"
From: orz on
On Aug 10, 5:54 pm, Gib Bogle <g.bo...(a)auckland.no.spam.ac.nz> wrote:
> orz wrote:
> > If I made yet another mistake on that then I'm going to throw
> > something.
>
> > It produced identical results for me when I tried it in C using this
> > code:
>
> > typedef unsigned int Uint32;
> > Uint32 sign(Uint32 value) {return value>>31;}
> > Uint32 index, carry, data[4691];
> > Uint32 mwc4691() {
> >    index = (index < 4690) ? index + 1 : 0;
> >    Uint32 x = data[index];
> >    Uint32 t = (x << 13) + carry + x;
> >    if (sign((x<<13)+carry) == sign(x))
> >            carry = sign(x) + (x>>19);
> >    else carry = 1 - sign(t) + (x>>19);
> >    data[index] = t;
> >    return t;
> > }
>
> > I think the only difference between that and the algorithm he
> > expressed in pseudocode is that I added parentheses on the first left-
> > shift (he was apparently assuming higher precedence on the leftshift
> > operator than C uses).  Maybe that's why you're getting different
> > results?
>
> You do realize that there's no unsigned integer type in Fortran?  I don't think
> there's much point in trying to predict what the Fortran code does without using
> a Fortran compiler.  Don't you have one?

Let me add another qualifier. The psuedocode he posted is correct
given the following assumptions:
1. The integers are 32 bit integers.
2. The "sign" function returns the value right-shifted by 31 bits (0
for non-negative, 1 for negative).
3. Shift operators are treated as higher precedence or parentheses
are added around that shift.
4. The right-shifts are treated as unsigned right-shifts.

Aside from those qualifiers, the results are independent of whether
the numbers are considered to be signed or unsigned. I probably
should have mentioned #4, but since I believe Fortran treats all right-
shifts as unsigned, it should not matter in Fortran.

Some C code which produces identical results and illustrates that:

typedef unsigned int Uint32;
typedef signed int Sint32;
Sint32 index, carry, data[4691];
Sint32 rshift(Sint32 value, int bits) {return Uint32(value)>>bits;}
Sint32 sign(Sint32 value) {return rshift(value,31);}
Sint32 mwc4691() {
index = (index < 4690) ? index + 1 : 0;
Sint32 x = data[index];
Sint32 t = (x << 13) + carry + x;
if (sign((x<<13)+carry) == sign(x)) carry = sign(x) + rshift(x,19);
else carry = 1 - sign(t) + rshift(x,19);
data[index] = t;
return t;
}

Perhaps you could post the Fortran code that is producing incorrect
results?