From: Gib Bogle on 10 Aug 2010 14:02 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 10 Aug 2010 15:32 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 10 Aug 2010 20:54 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 10 Aug 2010 21:35 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 10 Aug 2010 23:25
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? |