Prev: solutions book
Next: real kind declaration
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?
From: Richard Maine on 11 Aug 2010 00:36 Dann Corbit <dcorbit(a)connx.com> wrote: > In article <i3ssd1$be8$1(a)speranza.aioe.org>, > g.bogle(a)auckland.no.spam.ac.nz says... > > You do realize that there's no unsigned integer type in Fortran? .... > Maybe he is using Sun's Fortran 95 compiler. Though if my admittedly fallible memory serves me, the unsigned integer in Sun's f95 has restrictions that are likely to surprise many casual users. Being more specific might stretch my memory a bit farther than I trust, but I think I recall a lack of mixed-mode operations, for example. So one would have to tread pretty carefully in order to correctly transcribe pseudocode into working code. For example, I'm not at all sure that one can do such things as adding 1 to an unsigned integer; I think you might have to add 1U instead. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
From: glen herrmannsfeldt on 11 Aug 2010 00:47 In comp.lang.fortran orz <cdhorz(a)gmail.com> wrote: (snip) > 3. Shift operators are treated as higher precedence or parentheses > are added around that shift. The C precedence rules for shifts are widely believed to be wrong, including by the developers of C, but it is considered too late to change. Best to always use parentheses around them. (Many Fortran rules haven't been changed for the same reason.) -- glen
From: robin on 12 Aug 2010 09:49
"Gib Bogle" <g.bogle(a)auckland.no.spam.ac.nz> wrote in message news:i3ssd1$be8$1(a)speranza.aioe.org... | 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. It's perfectly possible to predict how to program the operation (unsigned arithmetic) in Fortran provided that we make the assumption that the hardware provides twos complement arithmetic. |