Google 网上论坛不再支持新的 Usenet 帖子或订阅项。历史内容仍可供查看。

Form k = i + j and test for overflow.

已查看 24 次
跳至第一个未读帖子

George Marsaglia

未读,
2007年6月18日 16:45:172007/6/18
收件人
My recent query on use of Fortran to carry out the
essential operation for multiply-with-carry:

Form t = a*x+c in 64 bits, get top and bottom 32 bits of t

led to a number of interesting responses, and
my conclusion that use of unsigned integers
is not yet sufficiently established to justify
recommending their use for implementations of the
KISS (Keep It Simple Stupid) RNG, versions of
which are apparently in some Fortran libraries,
except that the MWC component of the three
Simple parts that KISS uses has to be carried
out by concatenating pairs of 16-bit versions.

An alternative is to use AWC, add-with-carry,
for the third Simple part of the KISS RNG,
and the difficult part for Fortran versions
then becomes: decide when the addition of two 32-bit
patterns causes overflow.

So I seek advice on the best Fortran code
for determining whether the Fortran statement
k = i + j
causes overflow for non-zero i and j.

For unsigned non-zero i and j, as in C,
k = i + j
overflows if and only if k < i,
but Fortran seems to require some five or
more integer instructions.
I invite suggestions for those best for speed,
or best for shortest or most elegant code.

George Marsaglia

glen herrmannsfeldt

未读,
2007年6月18日 19:13:132007/6/18
收件人
George Marsaglia wrote:

> My recent query on use of Fortran to carry out the
> essential operation for multiply-with-carry:

> Form t = a*x+c in 64 bits, get top and bottom 32 bits of t

> led to a number of interesting responses, and
> my conclusion that use of unsigned integers
> is not yet sufficiently established to justify
> recommending their use for implementations of the
> KISS (Keep It Simple Stupid) RNG, versions of
> which are apparently in some Fortran libraries,
> except that the MWC component of the three
> Simple parts that KISS uses has to be carried
> out by concatenating pairs of 16-bit versions.

Signed integers in both C and Fortran are allowed to be
twos complement, ones complement, or sign magnitude. That
precludes many tricks that you might otherwise want to use,
even though there are no sign magnitude and very few ones
complement machines in production.

If you take twos complement as given, and that you get the
correct low order bits in the case of overflow, then you can
do both unsigned multiply and add.

> An alternative is to use AWC, add-with-carry,
> for the third Simple part of the KISS RNG,
> and the difficult part for Fortran versions
> then becomes: decide when the addition of two 32-bit
> patterns causes overflow.

> So I seek advice on the best Fortran code
> for determining whether the Fortran statement
> k = i + j
> causes overflow for non-zero i and j.

Assuming twos complement and wrap on overflow, i+j
can't overflow if i and j have different signs. If
they have the same sign, k will have a different
sign on overflow.

Neither Fortran nor C signed int guarantee anything
on overflow, but most satisfy the above condition.

Using IEOR and IAND, and assuming the appropriate word
length you can relatively easily and quickly determine
overflow, within the appropriate assumptions.

-- glen

Arjen Markus

未读,
2007年6月19日 05:18:572007/6/19
收件人

It may be a bit of trickery, but how about using
longer integers to do the computation and then
checking for overflow?

integer, parameter :: long_enough = selected_int_kind(10)
integer(kind=long_enough) :: i, j, k

k = i + j

if ( k > huge(10) ) then
... overflow ...
endif

(Most modern Fortran compilers seem to support a long integer
type nowadays ...)

Regards,

Arjen

anal...@hotmail.com

未读,
2007年6月19日 06:17:172007/6/19
收件人

Unless I am missing something

isn't it true that

overflow if and only if i not equal to k - j ?

glen herrmannsfeldt

未读,
2007年6月19日 08:30:152007/6/19
收件人
Arjen Markus wrote:

(snip)


> It may be a bit of trickery, but how about using
> longer integers to do the computation and then
> checking for overflow?

(snip)

> (Most modern Fortran compilers seem to support a long integer
> type nowadays ...)

How do you check for overflow of the longest integer supplied?

The OP seems to be worried about how fast things are, and
always wants to be as fast as possible. That means using
the longest possible integer type.

-- glen

Arjen Markus

未读,
2007年6月19日 09:14:382007/6/19
收件人

Hm, I assumed that 4-byte integers would be large enough for
most purposes. Then using 8-byte integers (or whatever larger integer
type is available) would provide an elegant solution
(one of the other possibilities ;))

Regards,

Arjen

James Giles

未读,
2007年6月19日 13:12:122007/6/19
收件人
anal...@hotmail.com wrote:
> On Jun 18, 4:45 pm, "George Marsaglia" <g...@stat.fsu.edu> wrote:
...

>> So I seek advice on the best Fortran code
>> for determining whether the Fortran statement
>> k = i + j
>> causes overflow for non-zero i and j.
...

> Unless I am missing something
>
> isn't it true that
>
> overflow if and only if i not equal to k - j ?

On a 2's complement machine i will *always* equal
k - j. That will be true whether overflow occured or
not. Integer arithmetic modulo 2^n is a ring.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


glen herrmannsfeldt

未读,
2007年6月19日 14:50:132007/6/19
收件人
James Giles wrote:

(someone wrote)

>>overflow if and only if i not equal to k - j ?

> On a 2's complement machine i will *always* equal
> k - j. That will be true whether overflow occured or
> not. Integer arithmetic modulo 2^n is a ring.

That is, assuming it doesn't do something else like enter
an interrupt routine. As I said before, the test is for
i and j to have the same sign, and k to have a different
sign. That should be easy to do with IEOR and IAND
or with logical operations. Using IEOR and IAND might
be faster but is less portable. (The OP seems to be
especially worried about speed.)

-- glen

glen herrmannsfeldt

未读,
2007年6月19日 14:55:202007/6/19
收件人
Arjen Markus wrote:

(snip)

> Hm, I assumed that 4-byte integers would be large enough for
> most purposes. Then using 8-byte integers (or whatever larger integer
> type is available) would provide an elegant solution
> (one of the other possibilities ;))

These days 32 bits (or 31) is often not enough for a random
number generator. There are many that are much wider than that, in
the hundreds of bits (for the internal state). Reasonably fast, too.

-- glen

Michael Metcalf

未读,
2007年6月19日 14:16:102007/6/19
收件人

"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
news:FLidnbKKco8Ki-Xb...@comcast.com...

(The OP seems to be
> especially worried about speed.)
>
> -- glen
>
For those who don't know, OP is the author of some of the world's most
renowned PRNGs, and they are used in situations where they are called 10**n
times (n not small).

Regards,

Mike Metcalf


James Giles

未读,
2007年6月19日 14:29:402007/6/19
收件人
glen herrmannsfeldt wrote:
> James Giles wrote:
>
> (someone wrote)
>
>>> overflow if and only if i not equal to k - j ?
>
>> On a 2's complement machine i will *always* equal
>> k - j. That will be true whether overflow occured or
>> not. Integer arithmetic modulo 2^n is a ring.
>
> That is, assuming it doesn't do something else like enter
> an interrupt routine. [...]

Of course that's the real answer to the OP. Most hardware
has some support for efficiently detecting integer overflow.
What's needed is to have some means of using that. The
Fortran standard says nothing about overflow, so whatever
you do will be beyond the scope of the standard and not
universally portable.

dpb

未读,
2007年6月19日 14:35:392007/6/19
收件人
Michael Metcalf wrote:
> "glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
> news:FLidnbKKco8Ki-Xb...@comcast.com...
> (The OP seems to be
>> especially worried about speed.)
>>
>> -- glen
>>
> For those who don't know, OP is the author of some of the world's most
> renowned PRNGs,...

Yes, I immediately recognized that and it's been kinda' kewl watching... :)

--

glen herrmannsfeldt

未读,
2007年6月19日 15:56:562007/6/19
收件人
(not posted)

Michael Metcalf wrote:
(snip)

> For those who don't know, OP is the author of some of the world's most
> renowned PRNGs, and they are used in situations where they are called 10**n
> times (n not small).

I didn't recognize the name, but he seems to have a wikipedia entry.

I am a little surprised, then, that he missed the fact that his first
example didn't generate the carry. In addition to pointing it out
in a post, I sent a separate (different) e-mail directly. Still
no acknowledgment to me or the group.

He also doesn't seem to understand the difference between signed and
unsigned multiply, surprising for a computer science professor.

At the time, I thought he might be a college student.

thanks,

-- glen

Steven G. Kargl

未读,
2007年6月19日 17:29:322007/6/19
收件人
In article <D6SdnavY8YWnu-Xb...@comcast.com>,

glen herrmannsfeldt <g...@ugcs.caltech.edu> writes:
>
> He also doesn't seem to understand the difference between signed and
> unsigned multiply, surprising for a computer science professor.
>

Marsaglia is a mathematician/statistian first. The fact that
he is an emeritus professor of Pure and Applied Mathematics
and Computer Science at WSU. In fact, 15 years when I was at
WSU, Pure and Applied Mathematics was one department and
Computer Science was another.

BTW, you may want to peek at the internals of random_number
within gfortran. It uses 1 or more KISS generators.

--
Steve
http://troutmask.apl.washington.edu/~kargl/

George Marsaglia

未读,
2007年6月19日 17:55:262007/6/19
收件人

"Michael Metcalf" <michael...@compuserve.com> wrote in message
news:K3Vdi.9313$M%4.3730@trndny08...
I don't know what OP is either, but then I do not read about what
others have done, preferring to undertake developments of my own.
But I would guess that I can provide RNGs with much longer periods,
(how about 10**49670), performance at least as well on tests of
randomness, faster and with much simpler code than any you can
point to, unless, of course, some are on things I have done.

The recent posts to this group are related to details of Fortran versions
directed toward accomplishing those goals. I have no reluctance in
asking experts for that. (Several C improvements have come
from the C newsgroups.)

George Marsaglia


Richard Maine

未读,
2007年6月19日 18:15:212007/6/19
收件人
George Marsaglia <g...@stat.fsu.edu> wrote:

> "Michael Metcalf" <michael...@compuserve.com> wrote in message
> news:K3Vdi.9313$M%4.3730@trndny08...

> > For those who don't know, OP is the author of some of the world's most


> > renowned PRNGs, and they are used in situations where they are called
> > 10**n times (n not small).

> I don't know what OP is either, but then I do not read about what


> others have done, preferring to undertake developments of my own.
> But I would guess that I can provide RNGs with much longer periods,
> (how about 10**49670), performance at least as well on tests of
> randomness, faster and with much simpler code than any you can
> point to, unless, of course, some are on things I have done.

Sound of amused laughter. I might say LOL, but perhaps it might not be
understood. (That's chat-speak for "Laughing Out Loud".)

OP is usenet shorthand for "Original Poster". In this thread, that would
be you, George. So Michael was referring to your own work.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain

George Marsaglia

未读,
2007年6月19日 18:48:382007/6/19
收件人

"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
news:FLidnbKKco8Ki-Xb...@comcast.com...
> James Giles wrote:
>
> (someone wrote)
>
>>>overflow if and only if i not equal to k - j ?
>
>> On a 2's complement machine i will *always* equal
>> k - j. That will be true whether overflow occured or
>> not. Integer arithmetic modulo 2^n is a ring.
>
> That is, assuming it doesn't do something else like enter
> an interrupt routine. As I said before, the test is for
> i and j to have the same sign, and k to have a different
> sign.

After your recent very helpful comments on getting the top
and bottom 32-bits from a 64-bit t = a*x+c,
I am reluctant to contest that last point on getting the
overflow bit after forming k = i+j.

As I often used in the graduate course,
Computer methods in probability and statistics,
that I gave for some 25 years in the 70-90's,
the relation between i,j and k in k = i+j for
signed integers can be illustrated by using the
addition table for 3-bit words:

addition mod 8, signed integers
j
0 1 2 3 -4 -3 -2 -1.
+ |000|001|010|011|100|101|110|111|
0 000| 0| 1| 2| 3| -4| -3| -2| -1|
1 001| 1| 2| 3| -4| -3| -2| -1| 0|
2 010| 2| 3| -4| -3| -2| -1| 0| 1|
i 3 011| 3| -4| -3| -2| -1| 0| 1| 2|
-4 100| -4| -3| -2| -1| 0| 1| 2| 3|
-3 101| -3| -2| -1| 0| 1| 2| 3| -4|
-2 110| -2| -1| 0| 1| 2| 3| -4| -3|
-1 111| -1| 0| 1| 2| 3| -4| -3| -2|

There is overflow if, and only if, the the i+j
result is below the / diagonal,
(lower-left to upper-right).

Let s(i) indicate the sign bit of i.
If s(i) = s(j), carry bit = s(i).
If s(i) != s(j), carry bit = complement of s(i+j).

I once again invite suggestions on
specific fast and/or elegant sets of Fortran
code for determining that carry bit.

George Marsaglia

(That addition table looked good when I typed it
on TextPad, but it looks suspicious pasted above, and
I cannot predict how it will appear when you see it.

Is there to a way guarantee that all typed characters
will use the same horizontal space, to enable proper
alignment of arrays or matrices posted to math-oriented
groups?)


glen herrmannsfeldt

未读,
2007年6月19日 19:59:062007/6/19
收件人
George Marsaglia wrote:

(snip)

> I don't know what OP is either, but then I do not read about what
> others have done, preferring to undertake developments of my own.
> But I would guess that I can provide RNGs with much longer periods,
> (how about 10**49670), performance at least as well on tests of
> randomness, faster and with much simpler code than any you can
> point to, unless, of course, some are on things I have done.

I am sure that many in this group prefer to do things on their own.
There are some algorithms using XOR with large numbers of bits.
The relative speed of XOR and MUL will be processor dependent.

> The recent posts to this group are related to details of Fortran versions
> directed toward accomplishing those goals. I have no reluctance in
> asking experts for that. (Several C improvements have come
> from the C newsgroups.)

IA32 (that is the Intel name for 32 bit x86) g95 with -O3 optimization
will generate one multiply instruction for 32 bit integers converted
to 64 bits for the multiply. I was surprised to find you disagree
with the correction for generating an unsigned product from a signed
multiply. I don't know how well your generator will work with the
uncorrected product, but would be interested to know.

A paper on doing unsigned divide on machines with only signed divide
is in CACM 11(7), 517 with a correction in:

http://www.slac.stanford.edu/cgi-wrap/getdoc/slac-pub-0302.pdf

-- glen

Dr Ivan D. Reid

未读,
2007年6月20日 03:33:312007/6/20
收件人
On Tue, 19 Jun 2007 18:48:38 -0400, George Marsaglia <g...@stat.fsu.edu>
wrote in <n56dnU1YDOXawOXb...@comcast.com>:

> addition mod 8, signed integers
> j
> 0 1 2 3 -4 -3 -2 -1.
> + |000|001|010|011|100|101|110|111|
> 0 000| 0| 1| 2| 3| -4| -3| -2| -1|
> 1 001| 1| 2| 3| -4| -3| -2| -1| 0|
> 2 010| 2| 3| -4| -3| -2| -1| 0| 1|
> i 3 011| 3| -4| -3| -2| -1| 0| 1| 2|
> -4 100| -4| -3| -2| -1| 0| 1| 2| 3|
> -3 101| -3| -2| -1| 0| 1| 2| 3| -4|
> -2 110| -2| -1| 0| 1| 2| 3| -4| -3|
> -1 111| -1| 0| 1| 2| 3| -4| -3| -2|

> Is there to a way guarantee that all typed characters
> will use the same horizontal space, to enable proper
> alignment of arrays or matrices posted to math-oriented
> groups?)

It helps to use a fixed-pitch font, like Courier, to type things
out. This will not line up if the viewer uses a proportional font, but
he can switch to a fixed font to see the original effect -- unlike someone
using a fixed-pitch font[1] to view text formatted with a proportional font.

[1] Or, I guess, a proportional font with different widths and kerning.

--
Ivan Reid, School of Engineering & Design, _____________ CMS Collaboration,
Brunel University. Ivan.Reid@[brunel.ac.uk|cern.ch] Room 40-1-B12, CERN
KotPT -- "for stupidity above and beyond the call of duty".

George Marsaglia

未读,
2007年6月20日 06:00:372007/6/20
收件人

"Dr Ivan D. Reid" <Ivan...@brunel.ac.uk> wrote in message
news:slrnf7hm2a....@loki.brunel.ac.uk...

I view newsgroups on Outlook Express
via newsgroups.comcast.net.
When , as now, I use the 'Reply Group'
box to open a reply window, clicking Format
leaves 'Style' and 'Font' unselectable.
I tried the selectable 'Plain Text' and 'Rich Text (HTML)' options;
neither got the spacing right.
Are there other options or do I need a different way to
access newsgroups?

George Marsaglia
Apparently, to my chagrin, an OP


Dan Nagle

未读,
2007年6月20日 08:03:422007/6/20
收件人
Hello,

George Marsaglia wrote:

> I view newsgroups on Outlook Express
> via newsgroups.comcast.net.

I use Thunderbird. It's free, and the folks
who understand these things think it's better (in my experience anyway).

> When , as now, I use the 'Reply Group'
> box to open a reply window, clicking Format
> leaves 'Style' and 'Font' unselectable.
> I tried the selectable 'Plain Text' and 'Rich Text (HTML)' options;
> neither got the spacing right.
> Are there other options or do I need a different way to
> access newsgroups?

I would simply use 'Plain Text' for Usenet,
and don't worry about it. In many cases, fonts
are selected by the reader, not the poster.
HTML is Evil on Usenet (or, IMNSHO, in email).
My spam filter kills HTML on sight.

> George Marsaglia
> Apparently, to my chagrin, an OP

Why the chagrin? Everyone asks questions. :-)
"That's why we're here."

--

Dan Nagle
Purple Sage Computing Solutions, Inc.

Jugoslav Dujic

未读,
2007年6月20日 08:34:132007/6/20
收件人
George Marsaglia wrote:
<snip>
|| It helps to use a fixed-pitch font, like Courier, to type things
|| out. This will not line up if the viewer uses a proportional font, but
|| he can switch to a fixed font to see the original effect -- unlike someone
|| using a fixed-pitch font[1] to view text formatted with a proportional
|| font.
||
|| [1] Or, I guess, a proportional font with different widths and kerning.
||
|| --
|| Ivan Reid, School of Engineering & Design, _____________ CMS
|| Collaboration,
|| Brunel University. Ivan.Reid@[brunel.ac.uk|cern.ch] Room 40-1-B12,
|| CERN
|| KotPT -- "for stupidity above and beyond the call of duty".
|
| I view newsgroups on Outlook Express
| via newsgroups.comcast.net.
| When , as now, I use the 'Reply Group'
| box to open a reply window, clicking Format
| leaves 'Style' and 'Font' unselectable.
| I tried the selectable 'Plain Text' and 'Rich Text (HTML)' options;
| neither got the spacing right.
| Are there other options or do I need a different way to
| access newsgroups?
|
| George Marsaglia
| Apparently, to my chagrin, an OP

When you post or read "plain text" messages (as opposed to HTML ones, which
are frowned upon in this and many other newsgroups), you cannot format the
text. Instead, the Outlook Express uses the fonts set up in

Tools/Options menu/Read tab/Fonts... button

I've got "Courier new", Smallest selected for pretty much every code page
there (at least, do so for "Western European" and "Unicode") for *both*
"Proportional" and "Fixed-width" ones.

I warmly recommend DejaVu Sans Mono font:

http://dejavu.sourceforge.net/wiki/index.php/Download
http://dejavu.sourceforge.net/wiki/index.php/Image:Dejavu.png

--
Jugoslav
___________
www.xeffort.com

Please reply to the newsgroup.
You can find my real e-mail on my home page above.

robin

未读,
2007年6月20日 22:04:322007/6/20
收件人
"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
news:Fe2dnd4dGv9Yn-rb...@comcast.com...

> Assuming twos complement and wrap on overflow,

Twos complement does not wrap on overflow.


robin

未读,
2007年6月20日 22:04:342007/6/20
收件人
"George Marsaglia" <g...@stat.fsu.edu> wrote in message
news:n56dnU1YDOXawOXb...@comcast.com...

>
> "glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
> news:FLidnbKKco8Ki-Xb...@comcast.com...

> After your recent very helpful comments on getting the top

As others have pointed out, using the most-significant
bit as a means of determining whether there has been
a carry out of the word is not portable in Fortran.

Of course, if you are willing to assume that twos
complement machines will always be used,
along with the non-portability aspect, then:

if (iand(i, msb) == iand(j, msb) then
carry_out = msb
else
carry_out = iand(i+j, msb) - msb
end if
where msb = most-significant bit.

carry_out is negative when a carry out occurs.

And there's an equivalent using SIGN.

robin

未读,
2007年6月20日 22:04:332007/6/20
收件人
"George Marsaglia" <g...@stat.fsu.edu> wrote in message
news:n56dnU1YDOXawOXb...@comcast.com...

> Is there to a way guarantee that all typed characters


> will use the same horizontal space, to enable proper
> alignment of arrays or matrices posted to math-oriented
> groups?)

If you have it, Notepad uses fixed space per character.


robin

未读,
2007年6月20日 22:04:322007/6/20
收件人
"James Giles" <james...@worldnet.att.net> wrote in message
news:ogVdi.101589$Sa4....@bgtnsc05-news.ops.worldnet.att.net...

> glen herrmannsfeldt wrote:
> > James Giles wrote:
> >
> > (someone wrote)
> >
> >>> overflow if and only if i not equal to k - j ?
> >
> >> On a 2's complement machine i will *always* equal
> >> k - j. That will be true whether overflow occured or
> >> not. Integer arithmetic modulo 2^n is a ring.
> >
> > That is, assuming it doesn't do something else like enter
> > an interrupt routine. [...]
>
> Of course that's the real answer to the OP. Most hardware
> has some support for efficiently detecting integer overflow.
> What's needed is to have some means of using that. The
> Fortran standard says nothing about overflow, so whatever
> you do will be beyond the scope of the standard and not
> universally portable.

It's perfectly possible to detect integer overflow
and keep within the standard.

The means has already been suggested in this thread.


James Giles

未读,
2007年6月21日 01:47:262007/6/21
收件人
robin wrote:
...

> It's perfectly possible to detect integer overflow
> and keep within the standard.
>
> The means has already been suggested in this thread.

Then repost it. I've seen many things in this thread where
the code is conforming if and only if no overflow has occured.
Since overflow behavior is *not* part of the standard, the
compiler *could* start WWIII when it occurs. It's not among
the things the compiler is required to detect or report.

Take a possible INTEGER implementation where you use
"sub-normal" floats as the integer values (ie. a float with
the smallest supported exponent and explicit normalization
bit). When that overflows, the result is a normal float.
Overflow can be recognized by testing whether the exponent
part has the smallest value. But, overflow *doesn't* cause
sign changes, mathematically implausible results, or any
of the other things mentioned in this thread. It's a possible
implementation that I've seen recommended (since it eliminates
the need to support non-float arithmetic in the hardware's
instruction set). It does not in any way violate the Fortran
standard.

Yes, given this or many other possible means of implementing
the INTEGER data type, there *are* standard conforming code
sequences whichwouls detect it. You can mask out the exponent
part and compare it to the "sub-normal" value, for example.
However, the means is not portable to other implementations
(like 2's complement). Similarly, tests that assume 2's complement
don't port to implementations that are something else. The
tests are *not* universally portable. To be sure, 2's complement
is really-really close to universal these days. That could change
very quickly in some new hardware platform that does differently
gets popular.

*Efficient* tests are those that directly access the hardware
flag(s) that indicate integer overflow has occured.

James Giles

未读,
2007年6月21日 02:02:072007/6/21
收件人


Maybe not always, just on all implemetations
I've seen (lots).

Richard Maine

未读,
2007年6月21日 02:24:222007/6/21
收件人
James Giles <james...@worldnet.att.net> wrote:

> robin wrote:
> ...
> > It's perfectly possible to detect integer overflow
> > and keep within the standard.
> >
> > The means has already been suggested in this thread.
>
> Then repost it. I've seen many things in this thread where
> the code is conforming if and only if no overflow has occured.
> Since overflow behavior is *not* part of the standard, the
> compiler *could* start WWIII when it occurs. It's not among
> the things the compiler is required to detect or report.

Indeed, it is rather explicit that any program that generates an integer
overflow violates the standard. (There's a statement somewhere requiring
the results of operations to be within range). So it is a direct
contradition to talk about detecting integer overflow while staying
within the standard. If integer overflow occurred, then you are already
outside the standard.

Doing it on typical and common implementations is one thing; doing it
within the standard is another matter entirely.

But then Robin is in my killfile anyway (mostly for other reasons, but
about tertiarily because of the amazingly poor correlation between his
postings and matters of fact.) I wouldn't have seen this if it hadn't
been quoted.

James Van Buskirk

未读,
2007年6月21日 02:40:082007/6/21
收件人
"Jugoslav Dujic" <jdu...@yahoo.com> wrote in message
news:5dsl65F...@mid.individual.net...

> Tools/Options menu/Read tab/Fonts... button

I think he wants the Compose tab, but he will probably have
gotten a good enough hint from your message to find it.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Arjen Markus

未读,
2007年6月21日 02:51:572007/6/21
收件人
On 18 jun, 22:45, "George Marsaglia" <g...@stat.fsu.edu> wrote:
> My recent query on use of Fortran to carry out the
> essential operation for multiply-with-carry:
>
> Form t = a*x+c in 64 bits, get top and bottom 32 bits of t
>
> led to a number of interesting responses, and
> my conclusion that use of unsigned integers
> is not yet sufficiently established to justify
> recommending their use for implementations of the
> KISS (Keep It Simple Stupid) RNG, versions of
> which are apparently in some Fortran libraries,
> except that the MWC component of the three
> Simple parts that KISS uses has to be carried
> out by concatenating pairs of 16-bit versions.
>
> An alternative is to use AWC, add-with-carry,
> for the third Simple part of the KISS RNG,
> and the difficult part for Fortran versions
> then becomes: decide when the addition of two 32-bit
> patterns causes overflow.

>
> So I seek advice on the best Fortran code
> for determining whether the Fortran statement
> k = i + j
> causes overflow for non-zero i and j.
>
> For unsigned non-zero i and j, as in C,

> k = i + j
> overflows if and only if k < i,
> but Fortran seems to require some five or
> more integer instructions.
> I invite suggestions for those best for speed,
> or best for shortest or most elegant code.
>
> George Marsaglia

I think that there is an easy way to detect this.

Suppose i and j are both positive. Then, if k = i+j would be
larger than the maximum positive value that the data
type of i and j can hold, that would be overflow.

Say this value is M. Then:

if ( i+j > M ) then
overflow
endif

(if we could fit all values into the data type).

This is mathematically equivalent to:

if ( i > M-j ) then
overflow on computing i+j
endif

However, this rearrangement causes the values in the
expression to be _within_ the range for the data type.

So, the above is a simple means that is guaranteed to
be within the standard to detect integer overflow.

If both i and j are negative, a similar condition holds:

if ( i < Mneg - j ) then
overflow on computing i+j
endif

If i and j are of opposite sign, there can never be
an overflow.

Apologies for the long explanation and even more of them if
I am wrong. But I think this is an easy and robust check.

Regards,

Arjen

James Giles

未读,
2007年6月21日 03:37:302007/6/21
收件人
Arjen Markus wrote:
> On 18 jun, 22:45, "George Marsaglia" <g...@stat.fsu.edu> wrote:
...

>> So I seek advice on the best Fortran code
>> for determining whether the Fortran statement
>> k = i + j
>> causes overflow for non-zero i and j.
...

> I think that there is an easy way to detect this.
...

> if ( i > M-j ) then
> overflow on computing i+j
> endif
...

> If both i and j are negative, a similar condition holds:
>
> if ( i < Mneg - j ) then
> overflow on computing i+j
> endif
>
> If i and j are of opposite sign, there can never be
> an overflow.


This works better than the other methods posted in this
thread. I was assuming the challenge was more general
and the given example was a stand-in for detecting
overflow generally. That is: from the result of a
calculation can you tell whether an overflow occured?
This test predicts whether a specific calculation you
may not even have done yet *will* overflow. That's a
slightly different challenge.

Notice that your solution requires as much additional work
(actually more) as the calculation whose result you're testing.
It's unfortunately not a very fast, nor a short and elegant
solution. Those were the two properties the OP wanted.
Non-standard tests (look directly at the machine status word
to test the overflow flag, catch an exception, whatever) are
the ones likely to be fast, and they're more likely to be
succinct and elegant too. But, they're not portable.

I got into this thread in response to a "solution" that wouldn't
even work on the most common INTEGER implementation
around. I mainly don't want people to waste time on things
that often (or usually) don't work. Yours *should* work,
so perhaps I should have held my tongue (keyboard).

Jugoslav Dujic

未读,
2007年6月21日 06:38:342007/6/21
收件人
James Van Buskirk wrote:
| "Jugoslav Dujic" <jdu...@yahoo.com> wrote in message
| news:5dsl65F...@mid.individual.net...
|
|| Tools/Options menu/Read tab/Fonts... button
|
| I think he wants the Compose tab, but he will probably have
| gotten a good enough hint from your message to find it.

Yes, I missed that, but now I checked -- the setting there applies
only to the default font in HTML messages; while composing
plain text ones, the settings from "Read" tab are used. Intuitive.

Dick Hendrickson

未读,
2007年6月21日 11:01:322007/6/21
收件人
Richard Maine wrote:
> James Giles <james...@worldnet.att.net> wrote:
>
>> robin wrote:
>> ...
>>> It's perfectly possible to detect integer overflow
>>> and keep within the standard.
>>>
>>> The means has already been suggested in this thread.
>> Then repost it. I've seen many things in this thread where
>> the code is conforming if and only if no overflow has occured.
>> Since overflow behavior is *not* part of the standard, the
>> compiler *could* start WWIII when it occurs. It's not among
>> the things the compiler is required to detect or report.
>
> Indeed, it is rather explicit that any program that generates an integer
> overflow violates the standard. (There's a statement somewhere requiring
> the results of operations to be within range). So it is a direct
> contradition to talk about detecting integer overflow while staying
> within the standard. If integer overflow occurred, then you are already
> outside the standard.
>
> Doing it on typical and common implementations is one thing; doing it
> within the standard is another matter entirely.

Yes, but why not focus on detecting the overflow before it occurs?
That's within the standard.

Wouldn't something like
IF ( K .GT. huge(I) - I ) then
process overflow
ELSE
answer = I + K
END IF
work?

You'd have to think about the restrictions. Probably K and I must be
positive. Maybe it should be HUGE(I)/2 with perhaps a plus or minus 1.
Maybe you need a separate IF test for each combination of "sign bits" on
K and I.

But, I think, you can come up with a portable test that will pre-detect
the overflow and let you do the right thing.

Dick Hendrickson

Ron Shepard

未读,
2007年6月21日 11:02:372007/6/21
收件人
In article
<zvoei.198490$p47....@bgtnsc04-news.ops.worldnet.att.net>,
"James Giles" <james...@worldnet.att.net> wrote:

> >> Assuming twos complement and wrap on overflow,
> >
> > Twos complement does not wrap on overflow.
>
>
> Maybe not always, just on all implemetations
> I've seen (lots).

One might view the simple operation of adding -1 and +1 (or
incrementing a value of -1) to be an overflow wrap in two-complement
integer arithmetic. Also, when you increment the largest signed
integer positive value (0111...111) you get the smallest negative
value (1000...000) which could also be viewed as an overflow wrap.
It depends on the context as to which kind of overflow wrap you are
talking about.

$.02 -Ron Shepard

Terence

未读,
2007年6月22日 02:27:532007/6/22
收件人
Unfortunately, Notepad also breaks up the text lines with unwanted cr-
lf that match the existing window width on closing. It's useful but
gives me endless headaches on using it to prepare a source code
posting before the link times out. But it DOES handle upper ascii
table characters.

Terence

未读,
2007年6月22日 20:28:122007/6/22
收件人
No idea how that happened!

anal...@hotmail.com

未读,
2007年6月22日 20:57:272007/6/22
收件人

I think this question can be formulated independent of computers and
representation systems.

unsigned integers:

(1) you have integers i, j in 0 <= i <= M-1 and 0<=j <= M-1

and k = i + j (Mod M).

Let us define "overflow" as

k0= i +j (mod 1) not equal to k = i+j (mod M)

in this case overflow if and only if k < i

This is truly elegant - doesn't involve bits and bytes or knowledge of
M.

(2) In the signed integer case

you have integers i, j in -M <= i <= M-1 and -M <=j <= M-1

and k = i + j (Mod 2M)

"overflow" is defined as above:

k0= i +j (mod 1) not equal to k = i+j (mod 2M)


Glen Hermannsfeldt has given a solution in terms of the signs of i, j
and k.

Here is a solution (Arjen Markus's solution is very similar) that
closely resembles the unsigned integer case (which is presumably your
standard of elegance for this problem):

If i>=0, then overflow if and only if k < i + (-M)

If i < 0 then overflow if and only if k > i + (M-1)

It seems surprising that the "overflow" detection problem for signed
integers is a lot harder than the unsigned integer case.

robin

未读,
2007年6月22日 22:17:522007/6/22
收件人
"Richard Maine" <nos...@see.signature> wrote in message
news:1i014pq.5efd60vmdh96N%nos...@see.signature...

> James Giles <james...@worldnet.att.net> wrote:
>
> > robin wrote:
> > ...
> > > It's perfectly possible to detect integer overflow
> > > and keep within the standard.
>
> > > The means has already been suggested in this thread.
>
> > Then repost it. I've seen many things in this thread where
> > the code is conforming if and only if no overflow has occured.
> > Since overflow behavior is *not* part of the standard, the
> > compiler *could* start WWIII when it occurs. It's not among
> > the things the compiler is required to detect or report.
>
> Indeed, it is rather explicit that any program that generates an integer
> overflow violates the standard. (There's a statement somewhere requiring
> the results of operations to be within range). So it is a direct
> contradition to talk about detecting integer overflow while staying
> within the standard.

There is no contradiction. It's perfectly possible to detect overflow without
causing an overflow condition - whether recognized or not by the hardware.

> If integer overflow occurred, then you are already
> outside the standard.

It's not necessary to check for integer overflow by getting an integer
overflow and then testing for it.


robin

未读,
2007年6月22日 22:17:542007/6/22
收件人
"James Giles" <james...@worldnet.att.net> wrote in message
news:Ohoei.198434$p47....@bgtnsc04-news.ops.worldnet.att.net...

> robin wrote:
> ...
> > It's perfectly possible to detect integer overflow
> > and keep within the standard.
> >
> > The means has already been suggested in this thread.
>
> Then repost it. I've seen many things in this thread where
> the code is conforming if and only if no overflow has occured.

Then as it's obviously not one of those where overflow
actually occurs, you should be able to recognize
the means to avoid getting an actual overflow.

> Since overflow behavior is *not* part of the standard, the
> compiler *could* start WWIII when it occurs. It's not among
> the things the compiler is required to detect or report.
>
> Take a possible INTEGER implementation where you use
> "sub-normal" floats as the integer values (ie. a float with
> the smallest supported exponent and explicit normalization
> bit). When that overflows, the result is a normal float.
> Overflow can be recognized by testing whether the exponent
> part has the smallest value.

In the context of Fortran, this seems to be an impractical
solution.
May I suggest you think of an integer scheme that is simpler
and is capable of being implemented in a portable way.

> But, overflow *doesn't* cause sign changes,
> mathematically implausible results, or any
> of the other things mentioned in this thread. It's a possible
> implementation that I've seen recommended (since it eliminates
> the need to support non-float arithmetic in the hardware's
> instruction set). It does not in any way violate the Fortran
> standard.
>
> Yes, given this or many other possible means of implementing
> the INTEGER data type, there *are* standard conforming code
> sequences whichwouls detect it. You can mask out the exponent
> part and compare it to the "sub-normal" value, for example.
> However, the means is not portable to other implementations
> (like 2's complement). Similarly, tests that assume 2's complement
> don't port to implementations that are something else.

I said that already.

> The tests are *not* universally portable. To be sure, 2's complement
> is really-really close to universal these days. That could change
> very quickly in some new hardware platform that does differently
> gets popular.

There's little likelihood of that happening any time soon.

> *Efficient* tests are those that directly access the hardware
> flag(s) that indicate integer overflow has occured.

Again, that's an impractical proposal, and fails to deliver
an appropriate result in the context of using the result for
a double-length integer sum or product, as the OP sought.


James Giles

未读,
2007年6月22日 22:40:542007/6/22
收件人
robin wrote:
> "James Giles" <james...@worldnet.att.net> wrote in message
> news:Ohoei.198434$p47....@bgtnsc04-news.ops.worldnet.att.net...
...

>> Then repost it. I've seen many things in this thread where
>> the code is conforming if and only if no overflow has occured.
>
> Then as it's obviously not one of those where overflow
> actually occurs, you should be able to recognize
> the means to avoid getting an actual overflow.

Those were mentioned *after* you claimed the appropriate
method had been posted. And, as I've already pointed out,
they involve more work to conduct the test than the original
operation. That's hardly the succinct, elegant, or fast solution
the OP was interested in.

>> Take a possible INTEGER implementation where you use
>> "sub-normal" floats as the integer values (ie. a float with
>> the smallest supported exponent and explicit normalization
>> bit). When that overflows, the result is a normal float.
>> Overflow can be recognized by testing whether the exponent
>> part has the smallest value.
>
> In the context of Fortran, this seems to be an impractical
> solution.
> May I suggest you think of an integer scheme that is simpler
> and is capable of being implemented in a portable way.

That particular method *is* portable. It works with all
IEEE floating point hardware that supports "sub-normal"
numbers. And, it's quite practical. The practicality is
why I've heard it recommended. It eleimiates the need
for separate instructions to support integer and float.

>> *Efficient* tests are those that directly access the hardware
>> flag(s) that indicate integer overflow has occured.
>
> Again, that's an impractical proposal, and fails to deliver
> an appropriate result in the context of using the result for
> a double-length integer sum or product, as the OP sought.

On the contrary, the usual reason that the hardware supports
such flags is to provide for efficient implementation of
multiple precision. That was the only way to get reasonable
efficiency for what we now regard as *usual* precision
when the hardware only had 16 (or even 8) bit ints directly
supported.

robin

未读,
2007年6月23日 01:11:402007/6/23
收件人
From: "glen herrmannsfeldt" <g...@ugcs.caltech.edu>
Sent: Wednesday, June 20, 2007 4:55 AM

> Arjen Markus wrote:
>
> (snip)
>
> > Hm, I assumed that 4-byte integers would be large enough for
> > most purposes. Then using 8-byte integers (or whatever larger integer
> > type is available) would provide an elegant solution
> > (one of the other possibilities ;))
>
> These days 32 bits (or 31) is often not enough for a random
> number generator. There are many that are much wider than that, in
> the hundreds of bits (for the internal state). Reasonably fast, too.

I would say, more than "reasonably fast".
You should take a look at G. Masaglia & W. Tsang's paper,
"The 64-bit Universal RNG".


robin

未读,
2007年6月23日 10:40:392007/6/23
收件人
"James Giles" <james...@worldnet.att.net> wrote in message
news:zvoei.198490$p47....@bgtnsc04-news.ops.worldnet.att.net...

> robin wrote:
> > "glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
> > news:Fe2dnd4dGv9Yn-rb...@comcast.com...
> >
> >> Assuming twos complement and wrap on overflow,
> >
> > Twos complement does not wrap on overflow.
>
>
> Maybe not always, just on all implemetations
> I've seen (lots).

Only on all implementations of ones-complement machines.


robin

未读,
2007年6月23日 10:40:392007/6/23
收件人
"Terence" <tbwr...@cantv.net> wrote in message
news:1182493673.9...@g37g2000prf.googlegroups.com...

> Unfortunately, Notepad also breaks up the text lines with unwanted cr-
> lf that match the existing window width on closing.

Doesn't happen on my system. And I also use it for source,
with lines as long as 100, well off the screen.
Do you have a line length limit set? possibly in your mail program?

James Giles

未读,
2007年6月23日 17:32:002007/6/23
收件人

Yes 1's complement wraps. Also, 2's complement wraps.
And, unsigned integers wrap. In all cases the successor of
the largest value is the least value and the predecessor of
the least value is the largest value. That's what it means to
wrap. The only way an implementation won't wrap is if
overflow always generates an exception or halts without
generating a result at all. Even most implementations that
can generate such exceptions also generate a wrapped
result though. I've not seen any implementations that don't
wrap.

glen herrmannsfeldt

未读,
2007年6月23日 19:05:162007/6/23
收件人
James Giles wrote:

(snip)

> Yes 1's complement wraps. Also, 2's complement wraps.
> And, unsigned integers wrap. In all cases the successor of
> the largest value is the least value and the predecessor of
> the least value is the largest value. That's what it means to
> wrap. The only way an implementation won't wrap is if
> overflow always generates an exception or halts without
> generating a result at all. Even most implementations that
> can generate such exceptions also generate a wrapped
> result though. I've not seen any implementations that don't
> wrap.

I believe there are some that have the option to saturate.
That is, stay at the largest or smallest value.

-- glen

James Giles

未读,
2007年6月23日 18:23:162007/6/23
收件人

That might be interesting. I've not seen any. For 2's complement,
that would inconvenient since one of the main advantages is that
for add, subtract, and multiply the operations are bitwise identical
with unsigned arithmetic, but they overflow differently. Where
each wraps, the other is in the middle of its range. I wouldn't
expect a hardware designer to spoil such a convenience.

robin

未读,
2007年6月23日 22:55:172007/6/23
收件人
"James Giles" <james...@worldnet.att.net> wrote in message
news:WK%ei.111607$Sa4.1...@bgtnsc05-news.ops.worldnet.att.net...

> robin wrote:
> > "James Giles" <james...@worldnet.att.net> wrote in message
> > news:Ohoei.198434$p47....@bgtnsc04-news.ops.worldnet.att.net...
> ...
> >> Then repost it. I've seen many things in this thread where
> >> the code is conforming if and only if no overflow has occured.
> >
> > Then as it's obviously not one of those where overflow
> > actually occurs, you should be able to recognize
> > the means to avoid getting an actual overflow.
>
> Those were mentioned *after* you claimed the appropriate
> method had been posted.

Don't be absurd. I wouldn't have been able to make the
claim unless it had already been posted.

FYI, the suggested method had appeared 2 days earlier
than my post.


James Giles

未读,
2007年6月23日 23:46:582007/6/23
收件人
robin wrote:
> "James Giles" <james...@worldnet.att.net> wrote in message
> news:WK%ei.111607$Sa4.1...@bgtnsc05-news.ops.worldnet.att.net...
...

>> Those were mentioned *after* you claimed the appropriate
>> method had been posted.
>
> Don't be absurd. I wouldn't have been able to make the
> claim unless it had already been posted.

You make all sorts of claims (like F77 TRIM functions
and the like). The fact is that you didn't understand the
issue (and still don't if you think 2's complement dosn't
wrap) and you probably incorrectly believed a prior
solution was standard conforming.

> FYI, the suggested method had appeared 2 days earlier
> than my post.

The newsgroup is archived. Point to the appropriate
entry in Google groups or quit. As it happens, your claim
that "The means has already been suggested in this thread"
was posted only two days, four hours, and 19 minutes after
the first article of the thread. Only one response was posted
the same day as the original article - and its proposed
solution assumed 2's complement and that overflow had
already occurred. I reread the entire thread and *no*
article prior to your claim (by two days or two minutes)
said anything about avoiding the overflow entirely.

In fact, no solution has yet been proposed that meets
your original claim: "It's perfectly possible to detect integer
overflow and keep within the standard." The proposals that
avoid overflow entirely don't detect it, they (expensively)
make a separate analysis to avoid it. As I've already pointed
out, that's an answer to a different question than the OP
appears to have asked (I can't speak for him, but that's
how I read it). I any case, those solutions are neither fast,
succinct, or elegant - which *were* the criteria the OP
desired to judge the suggestions on.

Brooks Moses

未读,
2007年6月24日 00:28:032007/6/24
收件人
glen herrmannsfeldt wrote:
> James Giles wrote:

Moreover, James is wrong even on bog-normal two's-complement machines,
so long as he is writing Fortran and not assembly code.

Why? The value is _undefined_, and thus it may act like it does not
have a consistent value at all. This is not a theoretical consideration
that happens with weird hardware. This is a practical consideration
that happens with real, everyday systems. I've seen the examples, and
arguments about them, on the GCC mailing list -- refering to i686/Linux
machines, not some exotic weird embedded hardware.

The critical piece to remember here is that the computer is NOT
executing your source code. The computer is executing some machine code
which is generated by an optimizing compiler, and this machine code is
_only_ required to produce the same logic as your source code when your
source code is legal code. This is NOT THE SAME THING if your code does
illegal things like overflowing its integers.

Consider the following program, on a system where integer(kind=1) is an
8-bit value:

subroutine foo(k)
integer(kind=1) k
if k < 0 write(*,*) 'Impossible!'
end subroutine

program wwiii
integer(kind=1) i, j
i = 128
j = 128
if (i + j > 0)
call foo(i + j)
end if
end

So, what do you think: Will that print "Impossible!"?

It might very well print it. Compile it with an aggressive optimizer,
and the compiler may conclude that since i and j are both greater than
zero, then i + k must be greater than zero. So it may very well decide
at compile-time that the "if" will always be true, and not even bother
with the check at runtime. (But foo doesn't know that, and so it _does_
check at runtime.)

More to the point, consider this function:

logical function check_overflow(i, j)
check_overflow = .false.
if (i > 0 .and. j > 0) then
if (i + j < 0) check_overflow = .true.
end if
end function

By the same logic, the compiler is entirely justified -- and would be
standard-conforming -- to compile this as if it were merely

logical function check_overflow(i, j)
check_overflow = .false.
end function

Which means that, no, as far as you can tell, i + j doesn't ever wrap in
that function, even if it does elsewhere in the program with the same
exact i and j.

There have been serious proposals to implement this sort of optimization
in GCC for compiling C code, and it appears that they are likely to be
added (albeit with optional warnings, and options to turn it off). I
would not be surprised if they show up in Fortran code as well --
because, in most cases, they are beneficial.

- Brooks


--
The "bmoses-nospam" address is valid; no unmunging needed.

Brooks Moses

未读,
2007年6月24日 00:32:572007/6/24
收件人
James Giles wrote:

> glen herrmannsfeldt wrote:
>> I believe there are some that have the option to saturate.
>> That is, stay at the largest or smallest value.
>
> That might be interesting. I've not seen any. For 2's complement,
> that would inconvenient since one of the main advantages is that
> for add, subtract, and multiply the operations are bitwise identical
> with unsigned arithmetic, but they overflow differently. Where
> each wraps, the other is in the middle of its range. I wouldn't
> expect a hardware designer to spoil such a convenience.

But a compiler author might spoil it. Especially if spoiling it is a
side-effect of an optimization that is safe for legal code and speeds up
the SPEC results by a measurable amount.

glen herrmannsfeldt

未读,
2007年6月24日 02:10:512007/6/24
收件人
James Giles wrote:

> glen herrmannsfeldt wrote:
(snip)

>>I believe there are some that have the option to saturate.
>>That is, stay at the largest or smallest value.

> That might be interesting. I've not seen any.

See page 4:

http://download.intel.com/technology/itj/q31997/pdf/archite.pdf

> For 2's complement,
> that would inconvenient since one of the main advantages is that
> for add, subtract, and multiply the operations are bitwise identical
> with unsigned arithmetic, but they overflow differently. Where
> each wraps, the other is in the middle of its range. I wouldn't
> expect a hardware designer to spoil such a convenience.

Many machines use the same instructions for unsigned and twos
complement addition and subtraction. S/360 and successors don't
because of the way the condition code bits are done, though the
actual result bits will be the same.

For multiply with a double length product signed and unsigned
are different.

-- glen

glen herrmannsfeldt

未读,
2007年6月24日 02:18:332007/6/24
收件人
Brooks Moses wrote:

(snip)

> Consider the following program, on a system where integer(kind=1) is an
> 8-bit value:

> subroutine foo(k)
> integer(kind=1) k
> if k < 0 write(*,*) 'Impossible!'
> end subroutine

> program wwiii
> integer(kind=1) i, j
> i = 128
> j = 128
> if (i + j > 0)
> call foo(i + j)
> end if
> end

> So, what do you think: Will that print "Impossible!"?

Does the calling program need to know that the subroutine argument
is (kind=1)? Consider the same program with different KINDs or
REAL variables? One would not expect to call a subroutine without
matching the KIND of the actual and dummy arguments.

-- glen

James Giles

未读,
2007年6月24日 01:57:272007/6/24
收件人
Brooks Moses wrote:
> glen herrmannsfeldt wrote:
....

>> I believe there are some that have the option to saturate.
>> That is, stay at the largest or smallest value.
>
> Moreover, James is wrong even on bog-normal two's-complement machines, so
> long as he is writing Fortran and not assembly code.

Well, yes and no. There are other standards besides Fortran's.
If the implementor claims that integers are two's complement
but then violates the semantics of that form I suspect it won't
be a popular compiler. For example, I wouldn't touch such
a thing.

> Consider the following program, on a system where integer(kind=1) is
> an 8-bit value:
>
> subroutine foo(k)
> integer(kind=1) k
> if k < 0 write(*,*) 'Impossible!'
> end subroutine
>
> program wwiii
> integer(kind=1) i, j
> i = 128
> j = 128
> if (i + j > 0)
> call foo(i + j)
> end if
> end
>
> So, what do you think: Will that print "Impossible!"?

Well, the program violates the *Fortran* standard several times
(in ways the implementation is *not* required to detect or report).
Even if the implementer claims that integers are 2's complement
it may complian that 128 is not a valid 8-bit signed value (and
Fortran doesn't permit *any* KIND that's not signed). However,
an implementation that doesn't complain *and* doesn't generate
a result consistent with the documented arithmetic (2'c complement,
I postulating) is simply broken.

James Giles

未读,
2007年6月24日 02:05:032007/6/24
收件人
glen herrmannsfeldt wrote:
> James Giles wrote:
>
>> glen herrmannsfeldt wrote:
> (snip)
>
>>> I believe there are some that have the option to saturate.
>>> That is, stay at the largest or smallest value.
>
>> That might be interesting. I've not seen any.
>
> See page 4:
>
> http://download.intel.com/technology/itj/q31997/pdf/archite.pdf

Very interesting. And, for the special purpose of media
processing (probably not for much else) quite appropriate.

> Many machines use the same instructions for unsigned and twos
> complement addition and subtraction. S/360 and successors don't
> because of the way the condition code bits are done, though the
> actual result bits will be the same.

That's probably why the Intel (and competitors) produce *both*
kinds of overflow condition codes for arithmetic operations. The
programmer can then select the one that corresponds to the signed-
ness of the arithmetic being done.

Brooks Moses

未读,
2007年6月24日 04:28:332007/6/24
收件人
glen herrmannsfeldt wrote:

A fair point. I had originally written it as a contained subroutine,
and when I moved it to external to emphasize the separate compilation, I
forgot to declare it. So, please assume that it was declared properly
within the main program. :)

Brooks Moses

未读,
2007年6月24日 04:41:412007/6/24
收件人
James Giles wrote:
> Brooks Moses wrote:
>> glen herrmannsfeldt wrote:
> ....
>>> I believe there are some that have the option to saturate.
>>> That is, stay at the largest or smallest value.
>> Moreover, James is wrong even on bog-normal two's-complement machines, so
>> long as he is writing Fortran and not assembly code.
>
> Well, yes and no. There are other standards besides Fortran's.
> If the implementor claims that integers are two's complement
> but then violates the semantics of that form I suspect it won't
> be a popular compiler. For example, I wouldn't touch such
> a thing.

Can you provide an example of such a claim from actual documentation? I
can't find anything that fits that description in the docs for either of
the two compilers that I use -- the Intel Fortran compiler documents
that integers are _stored_ as two's complement, but it doesn't say
anything about what happens when they overflow (if overflow-checking is
turned off).

Dick Hendrickson

未读,
2007年6月24日 12:11:532007/6/24
收件人
Am I missing something here? In the main program, i+j has kind 1
because both operands are kind 1. The dummy in foo is also kind 1.
There's no problem, you don't need to declare anything else. It's
the programmer's responsibility to have the arguments match, but
you've done that.

Dick Hendrickson

Richard Maine

未读,
2007年6月24日 12:37:112007/6/24
收件人
Dick Hendrickson <dick.hen...@att.net> wrote:
> Brooks Moses wrote:
> > glen herrmannsfeldt wrote:
> >> Does the calling program need to know that the subroutine argument
> >> is (kind=1)? Consider the same program with different KINDs or
> >> REAL variables? One would not expect to call a subroutine without
> >> matching the KIND of the actual and dummy arguments.
> >
> > A fair point. I had originally written it as a contained subroutine,
> > and when I moved it to external to emphasize the separate compilation, I
> > forgot to declare it.

> Am I missing something here? In the main program, i+j has kind 1


> because both operands are kind 1. The dummy in foo is also kind 1.
> There's no problem, you don't need to declare anything else. It's
> the programmer's responsibility to have the arguments match, but
> you've done that.

I sometimes get confused by not following a tanget Glen has gone off on,
so the following wild stab might be nowhere close, but...

It occurs to me as possible that Glen might be asking whether an
explicit interface is needed. An explicit interface is one thing that is
not declared in the [elided] code. Having an explicit interface is not
directly related to having the kinds match (other than in that it helps
diagose errors of that sort), but it would relate to the calling program
"knowing" the kind of the arguments.

If that was what Glen was talking about, then the answer is "no". An
explicit interface is not required. There is nothing in the code in
question that is even vaguely related to any of the requirements for
explicit interfaces. In fact, there is little enough relation to raise
considerable question as to whether that's what he was talking about. As
I said, my guess might be way off.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain

anal...@hotmail.com

未读,
2007年6月24日 14:20:532007/6/24
收件人
> that there are no obvious deficiencies." -- C. A. R. Hoare- Hide quoted text -
>
> - Show quoted text -

I think the following detects "overflow" independent of programming
languages and number representations:

For integers i, j and an integer modulus M > 1, let us define
"overflow" as

k0= i +j (mod 1) not equal to k = i+j (mod M)

(1) unsigned integers:

you have integers i, j in 0 <= i <= M-1 and 0<=j <= M-1

and k = i + j (Mod M).

in this case overflow if and only if k < i

(2) signed integers:

you have integers i, j in -M <= i <= M-1 and -M <=j <= M-1

and k = i + j (Mod 2M)

"overflow" is defined as above:

k0= i +j (mod 1) not equal to k = i+j (mod 2M)

If i>=0, then overflow if and only if k < i + (-M)

If i < 0 then overflow if and only if k > i + (M-1)

(it might be possible to combine the two cases into one formula - but
I haven't been able to find it so far.)

James Giles

未读,
2007年6月24日 21:06:552007/6/24
收件人
Brooks Moses wrote:
...

> Can you provide an example of such a claim from actual documentation?
> I can't find anything that fits that description in the docs for
> either of the two compilers that I use -- the Intel Fortran compiler
> documents that integers are _stored_ as two's complement, but it
> doesn't say anything about what happens when they overflow (if
> overflow-checking is turned off).

So the industry-wide common understanding of what 2's
complement is and how it works doesn't count as sufficient?
Well, how do you know what "add" means if common
definitions don't apply.

Anyway, my old Intel document (and several other published
books on the CPU architecture) explain what 2's complement
is in great detail. So indeed do many books (maybe just older
ones?) that engineers use to lean how to make adders (and other
arithmetic) in hardware. Or, for that matter, try the wikipedia
under twos complement (confine your attention the what they
say is "usual"). The definition of 2's complement is independent
of what programming language you refer to. Indeed the appropriate
definition is to be found in the hardware manual for the platform
you're working on.

Last night you suggested I was forgetting that overflow violates
the Fortran standard. Well, I have been most emphatic and
consistent in this thread about that point. Maybe you are
confused because I have three distinct points I'm trying to make
and I haven't explicitly stated them. (I've also managed to get
side-tracked into detailed discussions of specific implementations
and other issues.)

One: my first response to this thread was prompted by a proposed
test that wouldn't work on the most common of implementations.
Other tests proposed only work if you assume one or other kind
of common implementations. There is no portable test for overflow
(as opposed to a preemptive test) that conforms to the Fortran standard.
This is in part because :-

Two: if an integer overflow occurs in a program, that program
violates the Fortran standard. I have said that more often an more
consistently than any other person on this thread.

Three: the standard conforming methods of preempting overflow
are slow, cumbersome, and bulky. This is especially irksome
since nearly all hardware has overflow detection within it. Access
to that common feature would be considerably faster, more succinct,
and more elegant than the preemptive tests that have been suggested
here. In fact, they'd be better than the implementation dependent
tests I mentioned in point one above. This is not a particularly
outrageous suggestion. Prior to F2003 there was no standard
way (within the *Fortran* standard anyway) to detect floating
point conditions - overflow for example. In fact, programs which
contained float overflow were in violation the Fortran standard.

I would suggest the following:

A) There should be a number specified by the standard that
HUGE(0) must equal or exceed. This permits programmers
to be confident that integer arithmetic that doesn't exceed
some (preferably large) value can be portably performed
by Fortran. My own preference for this value is (2^31-1).
Debate about the specific value to choose is a subject for a
different thread. This is a requirement on the default KIND
only. Other KINDs might violate this requirement.

B) For N an integer of any KIND, HUGE(N) should return
the actual maximal value of that KIND of integer. I've
heard arguments to the effect that HUGE only returns a
value that's approximately the maximal one (with some
arm-waving about what that means). There should be a
variation of HUGE that returns the minimal value of the
argument's KIND. Say, HUGE(N,BACK=.TRUE.), or
HUGE(N,.TRUE.) for short. The exact syntax is for another
thread.

A compliant implementation should guarantee that no
integer of the same kind as N has a value outside the range
specified by those two inquiries. All values in that range
(including the endpoints) must be valid (I say that because
some have argued that integer types in Fortran are allowed
to have gaps). Any operation whose result is supposed
to be of a given KIND but whose mathematical value exceeds
the range here specified is said to have overflowed (this
definition for the purposes of later discussion).

C) For most intrinsic integer operations (the set to include
at least +, -, *, and /) if the operands are in range and the
correct mathematical result is in range the standard should
require the result to be exact. I say this because I believe
that the current Fortran standard doesn't require it. And
the standard *should* require it. Oh, I've heard people
claim that the standard does (subtly) require correct arithmetic.
But I don't find the arguments convincing. In any case, I don't
want it subtle - I want it clear and explicit. The set of
operations for which exact arithmetic should be required
is the subject of another thread. The set should be as
large as possible.

D) The standard should specify a way for a program to
determine whether the implementation will halt on overflow
(or zero divide, for that matter) and whether that halting
behavior can be controlled. A model for this is the IEEE
halting mode control in F2003. What the meaning of not
halting when zero divide occurs is for another thread.
For overflow, see below.

E) If overflow doesn't halt the program, then the language
standard should specify the means by which conforming
implementations report the condition (and whether such
a report is even possible). The model for this is the IEEE
floating point stuff in the F2003 standard. There's an
inquiry to determine whether the features are supported,
and if they are the specific tests for conditions are also
standardized. The cost of such tests isn't zero, but it's
bound to be *much* more efficient than the preemptive
solutions suggested elsewhere in this thread. More succinct
and legible too.

For the sake of future discussion, let's call the inquiry about
whether the feature is supported I_OFFS_SUPPORT(N)
which returns .true. if the I_OFFS (Integer OverFlow Features
Specification) are supported for the KIND of N and .false.
otherwise. The actual name(s) of the inquiry would be the
subject of (no doubt prolonged) discussion.

Now, for this purpose I would prefer an exception handling
mechanism rather than what I describe above. But, I recognize
that the above is more likely to pass the committee. I have
my own ideas about how exception handling should work
that are the appropriate subject of another thread.

F) If the I_OFFS_SUPPORT inquiry is .true., an overflow
that doesn't cause the program to halt must result in a
wrapped answer. I would prefer that *all* integer
KINDs be required to wrap on overflow, but that's a
backward compatibility issue. Since almost all Fortran
implementations already support this part of my proposal,
this is the easiest part of the whole thing.

It's probably been about 28 years since I've used any
Fortran whose integers weren't 2's complement. Those
wrap (modulo 2^p, where p is the number of bits in the
representation). Before that I used some implementations
that used 1's complement. Those wrap (modulo 2^p-1).
I don't think I've ever used a Fortran implementation whose
integers didn't wrap (unless overflow also caused the
program to halt). I've used such integers other than in
Fortran and found them lacking.

G) H) ... I've probably forgotten *something*.

So, what I'm recommending is that overflow no longer be a
violation of the Fortran standard. That Fortran permit and
reasonably handle the condition.

Walter Spector

未读,
2007年6月24日 22:27:582007/6/24
收件人
James Giles wrote:
> ...

> G) H) ... I've probably forgotten *something*.

How about:

G.) Enhance the DPROD intrinsic to support INTEGER args and return
a 'double integer' result? (And signed vs unsigned might be selectable
via an optional argument.)

H.) Add an intrinsic routine to add two integers and return the
overflow bit?

W.

Walter Spector

未读,
2007年6月24日 22:36:482007/6/24
收件人
Walter Spector wrote:
>
> James Giles wrote:
> > ...
> > G) H) ... I've probably forgotten *something*.
>
> How about:
>
> G.) Enhance the DPROD intrinsic to support INTEGER args and return
> a 'double integer' result? (And signed vs unsigned might be selectable
> via an optional argument.)

Or alternatively, (since it would be a lot of work to support 'double
integers'), DPROD-like intrinsic that only returns the high-order
bits? (Many vendors have supported such an intrinsic over the years.)

Richard Maine

未读,
2007年6月24日 23:42:302007/6/24
收件人
Walter Spector <w6ws_xt...@earthlink.net> wrote:

> > G.) Enhance the DPROD intrinsic to support INTEGER args and return
> > a 'double integer' result? (And signed vs unsigned might be selectable
> > via an optional argument.)
>
> Or alternatively, (since it would be a lot of work to support 'double
> integers'), DPROD-like intrinsic that only returns the high-order
> bits? (Many vendors have supported such an intrinsic over the years.)

That would make more sense to me. It is a lot more general than going
back to the days of doing things specific to particular kinds. Real
double precision is already a bit of an anacronism; I much more see it
going away from reals than adding something like it to integers.

James Van Buskirk

未读,
2007年6月25日 01:11:162007/6/25
收件人
"James Giles" <james...@worldnet.att.net> wrote in message
news:PyEfi.220063$p47.1...@bgtnsc04-news.ops.worldnet.att.net...

> C) For most intrinsic integer operations (the set to include
> at least +, -, *, and /) if the operands are in range and the
> correct mathematical result is in range the standard should
> require the result to be exact.

But if the standard did this, it would probably write out truth
tables for LOGICAL operators, and vendors, in slavishly conforming
to them, would make it more difficult to identify compiler brand
at runtime.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


James Giles

未读,
2007年6月25日 01:48:492007/6/25
收件人
James Van Buskirk wrote:
> "James Giles" <james...@worldnet.att.net> wrote in message
> news:PyEfi.220063$p47.1...@bgtnsc04-news.ops.worldnet.att.net...
>
>> C) For most intrinsic integer operations (the set to include
>> at least +, -, *, and /) if the operands are in range and the
>> correct mathematical result is in range the standard should
>> require the result to be exact.
>
> But if the standard did this, it would probably write out truth
> tables for LOGICAL operators, and vendors, in slavishly conforming
> to them, would make it more difficult to identify compiler brand
> at runtime.

I suppose we could require compilers to encode their brand
name inside trailing digits of ATAN(1.0).

Gordon Sande

未读,
2007年6月25日 08:18:442007/6/25
收件人
On 2007-06-25 00:42:30 -0300, nos...@see.signature (Richard Maine) said:

> Walter Spector <w6ws_xt...@earthlink.net> wrote:
>
>>> G.) Enhance the DPROD intrinsic to support INTEGER args and return
>>> a 'double integer' result? (And signed vs unsigned might be selectable
>>> via an optional argument.)
>>
>> Or alternatively, (since it would be a lot of work to support 'double
>> integers'), DPROD-like intrinsic that only returns the high-order
>> bits? (Many vendors have supported such an intrinsic over the years.)
>
> That would make more sense to me. It is a lot more general than going
> back to the days of doing things specific to particular kinds. Real
> double precision is already a bit of an anacronism; I much more see it
> going away from reals than adding something like it to integers.

How about an integer multiply intrinsic that returns the low order and high
order parts of the product. Likewise for add. If one wants to generalize
it would accept a modulus with the default being implementation dependent
as the natural one for the hardware.

I have seen assembly language versions of these written for use with multiple
precision arithmetic packages. I recall that for add it helps to have three
inputs of "a", "b" and the previous carry.

Dick Hendrickson

未读,
2007年6月25日 11:14:532007/6/25
收件人
James Van Buskirk wrote:
> "James Giles" <james...@worldnet.att.net> wrote in message
> news:PyEfi.220063$p47.1...@bgtnsc04-news.ops.worldnet.att.net...
>
>> C) For most intrinsic integer operations (the set to include
>> at least +, -, *, and /) if the operands are in range and the
>> correct mathematical result is in range the standard should
>> require the result to be exact.
>
> But if the standard did this, it would probably write out truth
> tables for LOGICAL operators, and vendors, in slavishly conforming
> to them, would make it more difficult to identify compiler brand
> at runtime.
>
Ah, but it does have a truth table for the logical operations. Table
7.6 on page 136 in F2003 gives 'em all. I think all vendors
conform to them now ;) .

What's not specified is the bit pattern for true or false.

Dick Hendrickson

glen herrmannsfeldt

未读,
2007年6月25日 19:32:192007/6/25
收件人
Brooks Moses wrote:

OK, it should be fine. Somehow I missed that i and j were kind=1 when
I wrote that post. I believe, though, that it should not print
"Impossible!" for a standard complying program.

In C operations such as addition of types smaller than int are done
after converting to int. Also, function arguments smaller than int
are converted to int before the call. The result of an expression
could be different than the result assigned to the appropriate variable.
I don't believe that Fortran does the same thing.

The addition of two signed or unsigned char values in C is int,
while the addition of INTEGER(kind=1) in Fortran is INTEGER(kind=1).

The program should work the same as if k=i+j were done in the main
program, where i, j, and k are all INTEGER(kind=1).

-- glen

Terence

未读,
2007年6月25日 19:57:352007/6/25
收件人
I think you should reread Glen's original suggestion.

I restate the obvious: starting with addition:
Adding two un-overflowed two's complement-based values can only
overflow in addition if both were of the same sign. And any overflow
resulting is indicated by a different sign from (obviously) either of
the two original values. And the overflow amount is the value of the
sign bit treated as an unsigned values with all other lower bits zero.
Or more reasonable just add 1 to (or subtract one from, based on the
sign found) the high-order tracking counter of total overflow to date.

The overflow test is a simple test between two bits (XOR the two bits
and non-zero shows the overflow condition).
Upon this you can now build similar rules for subtraction.

Multiplication can be treated as repeated addition, (but I'm NOT
suggesting you do it that way); obviously one proceeds to rules for a
doubled bit width.

This is all so horribly old stuff, discussed and resolved way, but way
back, in handcoded machine language days.

Richard Maine

未读,
2007年6月25日 20:24:072007/6/25
收件人
Terence <tbwr...@cantv.net> wrote:

> I think you should reread Glen's original suggestion.

I find it amusing to see this posted as a followup to Glen himself. I
suppose this is just a typical confusion from using google groups and
you intended to post this as a followup to something else. As posted,
though, you appear to be telling Glen to reread his own suggestion. :-)

I can't actually tell who you were directing this at. I suppose it is
possible that you were actually directing it at Glen. :-)

John Harper

未读,
2007年6月25日 22:39:262007/6/25
收件人
In article <467DF2D3...@cits1.stanford.edu>,

Brooks Moses <bmoses...@cits1.stanford.edu> wrote:
>
>Consider the following program, on a system where integer(kind=1) is an
>8-bit value:
>
> subroutine foo(k)
> integer(kind=1) k
> if k < 0 write(*,*) 'Impossible!'
> end subroutine
>
> program wwiii
> integer(kind=1) i, j
> i = 128
> j = 128
> if (i + j > 0)
> call foo(i + j)
> end if
> end
>
>So, what do you think: Will that print "Impossible!"?

It won't compile with g95 even when the obvious syntax error
(missing "then")has been corrected. In g95, kind=1 has 8 bits, so
huge(1_1) is 127, and i = 128 overflows at compile time. The following
is an attempt to prevent the compile-time problem and see what is going
on. Subroutine foo(k) is as above but the main program is now:

program ww3
integer(kind=1):: i, j, h=-huge(1_1)-1
character :: hbits*32
write(hbits,"(B0)") h
write(*,*) 'Number of bits in kind 1 is',len_trim(hbits)
i = -h
j = -h
print "(A,I0)",' i,j=',i
print "(A,I0)",' i+j=',i+j
if (i + j > 0) then


call foo(i + j)
end if

end program ww3

Output from g95, Sun f95, NAG f95, Compaq f95, gfortran with no
options set:

Number of bits in kind 1 is 8
i,j=-128
i+j=0

-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand
e-mail john....@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045

Brooks Moses

未读,
2007年6月26日 02:26:492007/6/26
收件人
James Giles wrote:
> Brooks Moses wrote:
> ...
>> Can you provide an example of such a claim from actual documentation?
>> I can't find anything that fits that description in the docs for
>> either of the two compilers that I use -- the Intel Fortran compiler
>> documents that integers are _stored_ as two's complement, but it
>> doesn't say anything about what happens when they overflow (if
>> overflow-checking is turned off).
>
> So the industry-wide common understanding of what 2's
> complement is and how it works doesn't count as sufficient?
> Well, how do you know what "add" means if common
> definitions don't apply.

I was going to argue with this -- and, personally, my opinion _is_ that
the answer to your rhetorical question is "yes", and that one shouldn't
rely on the preservation of wrapping behavior under optimization because
it's not part of the "common definition of 'add'" even when it's part of
what the base-level hardware does.

But it occurs to me that I've gotten in rather more Usenet arguments
than I prefer lately (in other words, a positive number thereof), and
the truth is that I've got an opinion which is based on my experience,
and you've got one that's based on yours, and we've both clearly stated
them, and just re-asserting my opinion won't add a thing to the
discussion. Besides which, I know it's biased by the fact that I've
never written a program that would have been helped by assuming that
signed integer overflows wrapped, because I haven't written "that sort"
of program.

In any case, I'd wholeheartedly agree with you that some proper standard
way of handling and reporting an integer overflow would be a good thing
to have. (I also want an integer NaN, but that's something that would
have to happen in hardware, as far as I can tell.)

Oh, and thank you for the rather thorough reply. I found a lot of
thought-provoking stuff in it. :)

James Giles

未读,
2007年6月26日 04:35:182007/6/26
收件人
Brooks Moses wrote:
> James Giles wrote:
...
>> So the industry-wide common understanding of what 2's
>> complement is and how it works doesn't count as sufficient?
>> Well, how do you know what "add" means if common
>> definitions don't apply.
>
> I was going to argue with this -- and, personally, my opinion _is_
> that the answer to your rhetorical question is "yes", and that one
> shouldn't rely on the preservation of wrapping behavior under
> optimization because it's not part of the "common definition of
> 'add'" even when it's part of what the base-level hardware does.

Well I was going to argue with this, but since you aren't I won't.

I do want to clarify one thing. I mentioned the definiton of
"add" not to suggest that wrapping is part of it, but as
an example of another thing that *isn't* specified by the
Fortran standard. Your position seems to be that one can't
rely on anything unless it's clearly specified by the Fortran
standard and *only* the Fortran standard. Well the Fortran
standard fails to require quit a lot of common sense things
that programming would be impossible without. You have
to rely on knowledge, specifications, and documents outside
the Fortran standard as well.

Also, "optimizaton" is the wrong word for doing an add, testing
the overflow flag (without reporting its status to the programmer),
discarding the wrapped result already present as a result of the
add instruction, and going out to find some non-wrapped substitute
value. That takes more work on the part of the implementer, more
cpu cycles at run-time (at least when the overflow does occur), and
produces an answer that's less useful to many who care. What's
the motivation for an implementer to do such a thing? Fortunately,
"quality of implementation" concerns will prevent it.

Tobias Burnus

未读,
2007年6月26日 07:14:222007/6/26
收件人
On Jun 25, 7:48 am, "James Giles" <jamesgi...@worldnet.att.net> wrote:
> > But if the standard did this, it would probably write out truth
> > tables for LOGICAL operators, and vendors, in slavishly conforming
> > to them, would make it more difficult to identify compiler brand
> > at runtime.
>
> I suppose we could require compilers to encode their brand
> name inside trailing digits of ATAN(1.0).

I somehow think the proposed COMPILER_VERSION() inquiry function of
Fortran 2003 makes deciphering the brand easier - especially how to
organize who gets which digit ;-)
(ftp://ftp.nag.co.uk/sc22wg5/N1651-N1700/N1678.pdf)

Tobias

James Van Buskirk

未读,
2007年6月26日 20:46:232007/6/26
收件人
"Dick Hendrickson" <dick.hen...@att.net> wrote in message
news:NZQfi.118891$Sa4.1...@bgtnsc05-news.ops.worldnet.att.net...

> Ah, but it does have a truth table for the logical operations. Table
> 7.6 on page 136 in F2003 gives 'em all. I think all vendors
> conform to them now ;) .

If you say so...

C:\Program Files\Microsoft Visual Studio 8\James\clf\truth_tables>type
truth_tab
les.f90
! File: truth_tables.f90
! Public domain 2007 James Van Buskirk
module funcs
implicit none
contains
subroutine print_table(header, values)
character(*), intent(in) :: header
logical, intent(in) :: values(4,3)

write(*,'(a/a)') header, repeat('-',33)
write(*,'(3(2x,a9))') 'A','B','Result'
write(*,'(3(2x,a9))') merge(' .TRUE.','.FALSE.',transpose(values))
end subroutine print_table

subroutine print_not(values)
character(*), parameter :: header = 'NOT'
logical, intent(in) :: values(2,2)

write(*,'(a/a)') header, repeat('-',22)
write(*,'(2(2x,a9))') 'A','Result'
write(*,'(2(2x,a9))') merge(' .TRUE.','.FALSE.',transpose(values))
end subroutine print_not

subroutine gen_tables(inputs)
logical, intent(in) :: inputs(4) ! Afalse, Atrue, Bfalse, Btrue
character(20) header
logical values(4,3)
integer i

write(*,'(a,4(1x,z8.8)/)') 'Inputs:', transfer(inputs,(/1/))
values(:, 1:2) = reshape((/ inputs(1), inputs(3), &
inputs(1), inputs(4), &
inputs(2), inputs(3), &
inputs(2), inputs(4)/), &
(/4, 2/), order = (/2,1/))

forall(i = 2:3) values(i,3) = .NOT. values(i,1)
call print_not(values(2:3,1:3:2))
write(*,'()')

header = '.AND.'
forall(i = 1:4) values(i,3) = values(i,1) .AND. values(i,2)
call print_table(trim(header), values)
write(*,'()')

header = '.OR.'
forall(i = 1:4) values(i,3) = values(i,1) .OR. values(i,2)
call print_table(trim(header), values)
write(*,'()')

header = '.EQV.'
forall(i = 1:4) values(i,3) = values(i,1) .EQV. values(i,2)
call print_table(trim(header), values)
write(*,'()')

header = '.NEQV.'
forall(i = 1:4) values(i,3) = values(i,1) .NEQV. values(i,2)
call print_table(trim(header), values)
write(*,'()')
end subroutine gen_tables
end module funcs

program truth_tables
use funcs
implicit none

! call gen_tables((/.FALSE., .TRUE., .FALSE., .TRUE./))
! call gen_tables(transfer((/2,5,8,17/),(/.FALSE./)))
call gen_tables(transfer((/0,2,0,4/),(/.FALSE./)))
end program truth_tables

! End of file: truth_tables.f90
C:\Program Files\Microsoft Visual Studio 8\James\clf\truth_tables>ifort
/stand:f
95 truth_tables.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.

Microsoft (R) Incremental Linker Version 8.00.40310.39
Copyright (C) Microsoft Corporation. All rights reserved.

-out:truth_tables.exe
-subsystem:console
truth_tables.obj

C:\Program Files\Microsoft Visual Studio
8\James\clf\truth_tables>truth_tables
Inputs: 00000000 00000002 00000000 00000004

NOT
----------------------
A Result
.FALSE. .TRUE.
.TRUE. .TRUE.

.AND.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE.
.TRUE. .TRUE. .FALSE.

.OR.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

.EQV.
---------------------------------
A B Result
.FALSE. .FALSE. .TRUE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

.NEQV.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

Richard Maine

未读,
2007年6月26日 21:22:142007/6/26
收件人
James Van Buskirk <not_...@comcast.net> wrote:

> "Dick Hendrickson" <dick.hen...@att.net> wrote in message
> news:NZQfi.118891$Sa4.1...@bgtnsc05-news.ops.worldnet.att.net...
>
> > Ah, but it does have a truth table for the logical operations. Table
> > 7.6 on page 136 in F2003 gives 'em all. I think all vendors
> > conform to them now ;) .
>
> If you say so...

[example elided]

If I followed it correctly, the example illustrates "funny" behavior
related to non-portable forms of TRANSFER. The standard does not specify
what the results of such TRANSFER operations are, or even that they give
sensible logical values at all.

I see no violation of the standard here. Nor do I see any contradiction
of Dick's statement. When you use forms of TRANSFER like that, pretty
much all bets are off. You have probably put a bit pattern into a
logical variable that isn't a valid logical value. And no, nothing
guarantees that the compiler will protect you against such things.

James Van Buskirk

未读,
2007年6月26日 22:13:432007/6/26
收件人
"Richard Maine" <nos...@see.signature> wrote in message
news:1i0burc.at6tiq13sl0ukN%nos...@see.signature...

> If I followed it correctly, the example illustrates "funny" behavior
> related to non-portable forms of TRANSFER. The standard does not specify
> what the results of such TRANSFER operations are, or even that they give
> sensible logical values at all.

> I see no violation of the standard here. Nor do I see any contradiction
> of Dick's statement. When you use forms of TRANSFER like that, pretty
> much all bets are off. You have probably put a bit pattern into a
> logical variable that isn't a valid logical value. And no, nothing
> guarantees that the compiler will protect you against such things.

No you have not followed it correctly. Where I am using TRANSFER, in
years past others would have used EQUIVALENCE. There are 3 things a
vendor can try to achieve for logical operations:

o Syllogisms

o Masking

o C-interoperability.

If syllogisms are not preserved, there is no way the compiler can
optimize stuff like:

if(A) then
call truesub
else if(.NOT.A) then
call falsesub
else
call idunnosub
end if

Syllogism dictates that subroutine IDUNNOSUB should never be
invoked, so the compiler shouldn't even create a branch here,
much less insert an inlined optimized version at this point.

Masking has got to be in many old (pre MIL-STD 1753) programs
because it permitted the programmer to issue bitwise logical
operations on non-LOGICAL variables (to negate a floating point
value [don't laugh, that's the way SSE3 wants you to do it] or
to slice and dice integers like the buckets of bits they
really are at their cores.) Maybe this usage is obsolescent,
but the adherents of SUPER JAVA-JAVA X with FEATURE Y think
we all are anyhow.

The C-interoperability was better served by the way DVF/CVF/IFORT
used to handle things: .TRUE. meant LSB set, .FALSE. meant LSB
clear, .NOT., .AND., .OR., .EQV., and .NEQV meant bitwise NOT,
AND, OR, XNOR, and XOR. In that case when a C function returned
a value documented as boolean, it obviously did no good to
attempt to interpret the result as LOGICAL because true values
in C could be false in Fortran. 2 is an example. Thus one was
forced to do what has to be done with an alien object: use
TRANSFER to tear it apart and see what's inside. Something
like:

/* Returns 0 if everything went OK */
int C_boolean_function(struct nonono lalala);

couldn't be invoked via

if(C_boolean_function(nine99)) call error_sub

because it's reasonable for a C program to invoke some function
or check some pointer and if the value is not zero, return it
as an error status. Previously, C programmers would wake up in
a cold sweat thinking "what if one of those boolean values I
tested only with the possibilities 0 and 1 actually turned
out to be 6 through this mechanism?" With Intel's latest
betrayal of their costomer base as shown in my example, those
same C programmers can now just roll over and go back to
sleep contented, thinking "At least all those poor bastards
that use ifort have the same problem now."

The way to do it given the ancient DVF/CVF way was:

if(transfer(C_boolean_function(nine99),1) != 0) call error_sub

which was transportable even to other compilers that declared
the same API function as INTEGER instead of LOGICAL. Oh well,
too much time invested in this post already.

Richard Maine

未读,
2007年6月26日 22:32:022007/6/26
收件人
James Van Buskirk <not_...@comcast.net> wrote:

> "Richard Maine" <nos...@see.signature> wrote in message
> news:1i0burc.at6tiq13sl0ukN%nos...@see.signature...
>
> > If I followed it correctly, the example illustrates "funny" behavior
> > related to non-portable forms of TRANSFER. The standard does not specify
> > what the results of such TRANSFER operations are, or even that they give
> > sensible logical values at all.

> because it's reasonable for a C program to invoke some function


> or check some pointer and if the value is not zero, return it
> as an error status. Previously, C programmers would wake up in
> a cold sweat thinking "what if one of those boolean values I
> tested only with the possibilities 0 and 1 actually turned
> out to be 6 through this mechanism?" With Intel's latest
> betrayal of their costomer base as shown in my example, those
> same C programmers can now just roll over and go back to
> sleep contented, thinking "At least all those poor bastards
> that use ifort have the same problem now."

Not if those ifort users stick to standard Fortran, they won't have such
problems. Type-cheating and assuming things about bit representations of
logical values is not standard Fortran, whether you do it with
equivalence or transfer. Always has been. If anything, it was more
nonstandard with equivalence. With equivalence, such tricks are just
plain explicitly nonstandard. With transfer, there is this waffly
wording about the result being processor dependent.

Traditional C is very different here in that the same type is used for
"logicals" and integers (prior to the _Bool of c99, at least I think it
is new to C99).

Dick Hendrickson

未读,
2007年6月27日 10:49:102007/6/27
收件人
James Van Buskirk wrote:
> "Richard Maine" <nos...@see.signature> wrote in message
> news:1i0burc.at6tiq13sl0ukN%nos...@see.signature...
>
>> If I followed it correctly, the example illustrates "funny" behavior
>> related to non-portable forms of TRANSFER. The standard does not specify
>> what the results of such TRANSFER operations are, or even that they give
>> sensible logical values at all.
>
>> I see no violation of the standard here. Nor do I see any contradiction
>> of Dick's statement. When you use forms of TRANSFER like that, pretty
>> much all bets are off. You have probably put a bit pattern into a
>> logical variable that isn't a valid logical value. And no, nothing
>> guarantees that the compiler will protect you against such things.
>
> No you have not followed it correctly. Where I am using TRANSFER, in
> years past others would have used EQUIVALENCE.
>

Here's what I think is the nub of "your" problem ;). In years past,
others could NOT do this with EQUIVALENCE. If you equivalence a
logical and an integer variable and do something to one of them, the
other becomes undefined. It doesn't depend on the bit pattern, it
becomes undefined as a matter of law (or at least as a matter of
conformance).

The standard says that the logical type has two values, which represent
true and false. Putting other values into a logical variable makes
your program non-conforming.

Part of the problem is that the TRANSFER intrinsic was put in to allow
people to do the kind of thing Richard and I are yelling at you about.
Sometimes you need to poke around at the bits. But, it was never
expected to be "portable". It's too bad that wasn't said in the
description. For what it's worth, the new F2008 BIT stuff allows
conversions from bit to logical, but explicitly says you can only use
the result as a logical if you get the physical representation right.
It's too bad something similar wasn't put into transfer.

Dick Hendrickson

Brooks Moses

未读,
2007年6月28日 13:13:202007/6/28
收件人
James Van Buskirk wrote:
> If syllogisms are not preserved, there is no way the compiler can
> optimize stuff like:
>
> if(A) then
> call truesub
> else if(.NOT.A) then
> call falsesub
> else
> call idunnosub
> end if

I don't see how that follows, unless you require the optimized code to
produce the same result as the unoptimized code even when the program
being compiled is illegal. I don't think that's a reasonable thing to
expect a compiler to conform to.

Richard Maine

未读,
2007年6月28日 13:25:192007/6/28
收件人
Brooks Moses <bmoses...@cits1.stanford.edu> wrote:

> I don't see how that follows, unless you require the optimized code to
> produce the same result as the unoptimized code even when the program
> being compiled is illegal. I don't think that's a reasonable thing to
> expect a compiler to conform to.

And very often compilers don't. Illegal argument aliasing is a classic
case.

Brooks Moses

未读,
2007年6月28日 13:27:582007/6/28
收件人
James Van Buskirk wrote:
> /* Returns 0 if everything went OK */
> int C_boolean_function(struct nonono lalala);
>
> couldn't be invoked via
>
> if(C_boolean_function(nine99)) call error_sub
[...]

> The way to do it given the ancient DVF/CVF way was:
>
> if(transfer(C_boolean_function(nine99),1) != 0) call error_sub
>
> which was transportable even to other compilers that declared
> the same API function as INTEGER instead of LOGICAL.

I'm sort of baffled that one would take a C function that returns an
int, and declare it as anything _other_ than integer in Fortran, and
expect it to actually work reliably.

Well, I suppose if it's an API function specified by the compiler, then
perhaps it makes sense -- but, in that case, the authors of the compiler
are responsible for making sure that their compiler handles any weird
bit patterns in logical variables in the right way. If it doesn't, then
the fundamental problem is in their API, which is returning values that
their compiler considers invalid. That's a clear case of a compiler
implementation problem, and there's no point in getting the standard
involved when it already contradicts the compiler documentation.

James Van Buskirk

未读,
2007年6月29日 03:00:482007/6/29
收件人
"Brooks Moses" <bmoses...@cits1.stanford.edu> wrote in message
news:4683EF9E...@cits1.stanford.edu...

> I'm sort of baffled that one would take a C function that returns an int,
> and declare it as anything _other_ than integer in Fortran, and expect it
> to actually work reliably.

Mmmm... I guess this gives me another chance to try and explain the
inexplicable. One might equally well wonder why a C function that
returns an int would be declared to return anything other than an
int in C, but this is a natural effect of the way C handles boolean
data.

C itself has no boolean data type, but it has entities that require
them, such as if(), while(), do...while(), and for(). C, instead of
having an actual boolean data type, has a model for what bit patterns
will cause an int to be interpreted as true or false. Also it has
boolean (result) operators that return specified bit patterns for
the possible results, true or false. Thus it is quite normal for C
programs to write functions that return an int and then interpret the
result, because it is one of the specified result values for the
boolean operators, as a boolean and use it in context [if, while,
do...while, for].

As well, C programmers are encouraged to use any int as a boolean
value when the bit pattern of the int when interpreted as the bit
pattern of a boolean enables the programmer to at least partially
resolve success or failure of a previous operation. Thus a C
programmer can't say:

if(associated(ptr))...

because C doesn't have an ASSOCIATED intrinsic, and C programmers
mostly aren't told to say:

if(ptr == SPECIAL_VALUE)

but instead:

if(ptr)

because the programmer is supposed to be able to tell whether or
not ptr points at something useful from whether the bit pattern of
ptr maps to true or false.

The problem for C programs lies in the fact that C boolean operators
spit out unique values for true and false results but any int in C
has a documented interpretation as true or false even though it may
not match one of the two bit patterns above. As explained earlier,
this can lead to programs that count on one of the two unique bit
patterns, but this trust in input may not get tested because
normal testing only tests with normal inputs, and not the wide
spectrum of inputs that are possible. Really this looks like what
is happening with ifort and some of its buddies: for normal inputs,
the logical operators do the right thing, but since they didn't
get tested with any but normal inputs, all bets are off when
anything else is used as an input for a logical operator.

In C, there are bitwise logical operators [~,&,|,^] and boolean
logical operators [!,&&,||,missing] but in pre MIL-STD 1753
Fortran, there are only boolean logical operators [.NOT.,.AND.,
.OR.,.NEQV., and the bonus .EQV.] and no bitwise logical integer
functions. In Fortran, when a vendor chooses to use the C
documented bit patterns to define .TRUE. and .FALSE., they have
to make a choice whether to make the Fortran logical operators
act like C boolen logical operators (I think lf95 did this) or
like C bitwise logical operators (it looks like ifort now does
this :( ) or something utterly lame (at least pathscale use do
do this).

The way ifort used to do it, .TRUE. follows low bit of number,
allowed them to have logical operators that acted like bitwise
logical operators but also preserved syllogisms. C programmers,
whose idea of interoperability is to tear up any any language
and redefine it from scratch as C, were always complaining
that ifort didn't match their notion of what boolean data
should be represented as internally, and Intel has given in
to their ill-reasoned prejudice. They are eventually going to
complain that now ifort's logical operators don't match what C
boolean logical operator are documented to do, and Intel, for
certain, will cave on this as well and change how their
logical operators work. Of course this will break all that
fine old pre MIL-STD 1753 code that needed to do masking, as
well as all the modern code that uses their extension of using
intrinsic logical operators an integer inputs (and for that matter
mixed logical-integer inputs) but the C programmers will win again,
so ifort will make it easier for the C programmers to run
benchmarks they don't understand but make it impossible for
Fortran programmers to write new and innovative algorithms.
I'm sure they call that "progress" at Intel.

Could you guys write stuff a little less dopey in this thread?
I'm spending more time than I really should trying to make you
see what a problem Intel is making for its customers. Well, I
guess I shouldn't be so troubled about it since their latest
price hike took me out of their market in any case. You can
pay them for a year's support and request that they fix a bug
that causes their compiler to output incorrect results, and
after a year your contract has expired and they still haven't
fixed the bug. Too bad the free compilers are tied to gcc
and so will not, at least for a long time, support current
versions of Windows because that goes against the grain of
the irrational hostility of gnu types towards operating
systems that anyone can actually use.

James Giles

未读,
2007年6月29日 16:36:412007/6/29
收件人
James Van Buskirk wrote:
> "Brooks Moses" <bmoses...@cits1.stanford.edu> wrote in message
> news:4683EF9E...@cits1.stanford.edu...
>
>> I'm sort of baffled that one would take a C function that returns an
>> int, and declare it as anything _other_ than integer in Fortran, and
>> expect it to actually work reliably.
>
> Mmmm... I guess this gives me another chance to try and explain the
> inexplicable. One might equally well wonder why a C function that
> returns an int would be declared to return anything other than an
> int in C, but this is a natural effect of the way C handles boolean
> data.

But, the appropriate way to handle such from Fortran is to
declare the C function as returning a C_INT, and then using
an explicit C_INT_2_LOGICAL function to convert it for
use in your Fortran program. The C convention for what
integers mean when used in control expressions is not at
all necessarily the same as the Fortran implementation's
internal representation of LOGICALs. Using some type
cheat in the procedure's interface makes the code less clear
and leads to portability problems and likely to hidden errors.

> [...] Thus a C


> programmer can't say:
>
> if(associated(ptr))...
>
> because C doesn't have an ASSOCIATED intrinsic, and C programmers
> mostly aren't told to say:
>
> if(ptr == SPECIAL_VALUE)
>
> but instead:
>
> if(ptr)
>
> because the programmer is supposed to be able to tell whether or
> not ptr points at something useful from whether the bit pattern of
> ptr maps to true or false.

Except that the C standard itself explicitly states that the internal
representation of a null is not necessarily all zero bits. The C
standard also clearly states that a control construct's expression
is considered false if and only if the value the value compares
equal to integer zero. That involves an implicit cast to int for
any expression that's not integral. So, the only reason the above
works is that there is an implicit *conversion* of the pointer to
type int. Null pointers *are* guaranteed to *convert* to zero
integers.

But, conversion is not what type cheats do. Using a type cheat in
your procedure interface will not do the right thing. You have to
use a conversion: one that correctly utilizes the correct C convention
for control construct tests for the C implementation you're working
with and converts that to native Fortran LOGICALs.

Richard Maine

未读,
2007年6月29日 16:56:142007/6/29
收件人
James Giles <james...@worldnet.att.net> wrote:

> Using some type
> cheat in the procedure's interface makes the code less clear
> and leads to portability problems and likely to hidden errors.

[and other elided stuff]

In short, if you use nonstandard and nonportable practices, then you
sometimes run into trouble when porting code - sometimes even to the
same vendor's next version. This applies to Fortran and C, and pretty
much any other language. It has long been the case. It has also long
been the case that people bitch at vendors when their nonstandard and
nonportable code fails.

Gary Scott

未读,
2007年6月29日 17:07:282007/6/29
收件人
Richard Maine wrote:
> James Giles <james...@worldnet.att.net> wrote:
>
>
>>Using some type
>>cheat in the procedure's interface makes the code less clear
>>and leads to portability problems and likely to hidden errors.
>
> [and other elided stuff]
>
> In short, if you use nonstandard and nonportable practices, then you
> sometimes run into trouble when porting code - sometimes even to the
> same vendor's next version. This applies to Fortran and C, and pretty
> much any other language. It has long been the case. It has also long
> been the case that people bitch at vendors when their nonstandard and
> nonportable code fails.

More so however, when the vendor first did something the "right" way and
changed to do it the "wrong" way. For example, IBM once made a change
in VS Fortran that meant you could no longer initialize integers with
the max negative 32-bit integer value (-2147483648) commonly used to set
a specific bit pattern for binary flag values. At first they refused to
change it back claiming it was fully standard compliant, but after about
6 months of my first complaint (and an angry subsequent one), they
released an update that put it back the "correct" way.

>


--

Gary Scott
mailto:garylscott@sbcglobal dot net

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford

Terence

未读,
2007年6月29日 21:37:052007/6/29
收件人

>
> .EQV.
> ---------------------------------
> A B Result
> .FALSE. .FALSE. .TRUE. <---????

> .FALSE. .TRUE. .TRUE.
> .TRUE. .FALSE. .TRUE.
> .TRUE. .TRUE. .TRUE.
>

Surely the first line should be FALSE?

Wade Ward

未读,
2007年6月29日 22:58:062007/6/29
收件人

"Terence" <tbwr...@cantv.net> wrote in message
news:1183167425.2...@e9g2000prf.googlegroups.com...
Not sure of context, but "if false" is a fantastic premise and always true.
The one that looks wrong, if this is "if a then b," is the third one.
--
Wade Ward


glen herrmannsfeldt

未读,
2007年7月1日 09:21:212007/7/1
收件人
Gary Scott wrote:

> More so however, when the vendor first did something the "right" way and
> changed to do it the "wrong" way. For example, IBM once made a change
> in VS Fortran that meant you could no longer initialize integers with
> the max negative 32-bit integer value (-2147483648) commonly used to set
> a specific bit pattern for binary flag values. At first they refused to
> change it back claiming it was fully standard compliant, but after about
> 6 months of my first complaint (and an angry subsequent one), they
> released an update that put it back the "correct" way.

I would probably initialize with a hex constant, which hopefully
still worked. In C it is usual to use either the hex constant
or -2147483647-1, that is, a constant expression.

In expressions in both Fortran and C, constants are positive
and - is the unary negation operator. Initializers (for DATA
statements in Fortran 66) are specifically signed constants.
It would be usual, though likely not required, for signed
integer constant to include the most negative constant on
twos complement machines.

-- glen

glen herrmannsfeldt

未读,
2007年7月1日 09:31:172007/7/1
收件人
James Van Buskirk wrote:
(snip)

> because C doesn't have an ASSOCIATED intrinsic, and C programmers
> mostly aren't told to say:

> if(ptr == SPECIAL_VALUE)

> but instead:

> if(ptr)

> because the programmer is supposed to be able to tell whether or
> not ptr points at something useful from whether the bit pattern of
> ptr maps to true or false.

Note that for pointers, unlike other constants, the NULL pointer
is false and all others are true. While the usual NULL pointer
representation is all bits zero, the standard doesn't require
that. It does require that the constant zero cast to a pointer
be the NULL constant, though.

> The problem for C programs lies in the fact that C boolean operators
> spit out unique values for true and false results but any int in C
> has a documented interpretation as true or false even though it may
> not match one of the two bit patterns above.

With zero for false and non-zero for true. Now that you mention
it, I am not sure about negative zero....

-- glen

James Giles

未读,
2007年7月1日 16:52:562007/7/1
收件人
glen herrmannsfeldt wrote:
> James Van Buskirk wrote:
...

>> The problem for C programs lies in the fact that C boolean operators
>> spit out unique values for true and false results but any int in C
>> has a documented interpretation as true or false even though it may
>> not match one of the two bit patterns above.
>
> With zero for false and non-zero for true. Now that you mention
> it, I am not sure about negative zero....

The C standard is pretty clear that the control constructs are based
on a comparison to zero. Negative zero compares equal to zero.
So, negative zero is false in C.

robin

未读,
2007年7月2日 10:24:022007/7/2
收件人
"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
news:rpCdnVG0OYobBhrb...@comcast.com...

> Gary Scott wrote:
>
> > More so however, when the vendor first did something the "right" way and
> > changed to do it the "wrong" way. For example, IBM once made a change
> > in VS Fortran that meant you could no longer initialize integers with
> > the max negative 32-bit integer value (-2147483648) commonly used to set
> > a specific bit pattern for binary flag values. At first they refused to
> > change it back claiming it was fully standard compliant, but after about
> > 6 months of my first complaint (and an angry subsequent one), they
> > released an update that put it back the "correct" way.
>
> I would probably initialize with a hex constant,

And what happens when the word size changes?

? which hopefully still worked. In C it is usual to use either the hex constant


> or -2147483647-1, that is, a constant expression.
>
> In expressions in both Fortran and C, constants are positive
> and - is the unary negation operator. Initializers (for DATA
> statements in Fortran 66)

Is that relevant? That's 40 years ago.

robin

未读,
2007年7月2日 10:24:032007/7/2
收件人
"Terence" <tbwr...@cantv.net> wrote in message
news:1183167425.2...@e9g2000prf.googlegroups.com...

> > .EQV.

No, the first and last lines are correct; the others are incorrect.

robin

未读,
2007年7月2日 10:24:022007/7/2
收件人
"James Van Buskirk" <not_...@comcast.net> wrote in message
news:0YKdnV2h0KnHLhzb...@comcast.com...

> Inputs: 00000000 00000002 00000000 00000004


>
> NOT
> ----------------------
> A Result
> .FALSE. .TRUE.
> .TRUE. .TRUE.

Um?

> .AND.
> ---------------------------------
> A B Result
> .FALSE. .FALSE. .FALSE.
> .FALSE. .TRUE. .FALSE.
> .TRUE. .FALSE. .FALSE.
> .TRUE. .TRUE. .FALSE.

Um?

> .OR.
> ---------------------------------
> A B Result
> .FALSE. .FALSE. .FALSE.
> .FALSE. .TRUE. .TRUE.
> .TRUE. .FALSE. .TRUE.
> .TRUE. .TRUE. .TRUE.
>
> .EQV.
> ---------------------------------
> A B Result
> .FALSE. .FALSE. .TRUE.
> .FALSE. .TRUE. .TRUE.
> .TRUE. .FALSE. .TRUE.
> .TRUE. .TRUE. .TRUE.
>
> .NEQV.
> ---------------------------------
> A B Result
> .FALSE. .FALSE. .FALSE.
> .FALSE. .TRUE. .TRUE.
> .TRUE. .FALSE. .TRUE.
> .TRUE. .TRUE. .TRUE.

What is this supposed to show?
Will any Fortran compiler produce the correct values with this code?


James Van Buskirk

未读,
2007年7月2日 15:39:282007/7/2
收件人
"robin" <rob...@bigpond.com> wrote in message
news:6U7ii.2252$4A1....@news-server.bigpond.net.au...

> "James Van Buskirk" <not_...@comcast.net> wrote in message
> news:0YKdnV2h0KnHLhzb...@comcast.com...

>> C:\Program Files\Microsoft Visual Studio 8\James\clf\truth_tables>type

That ifort no longer supports syllogisms.

> Will any Fortran compiler produce the correct values with this code?

Since I had my old Athlon running anyhow, I tried but the version
as quoted above and an alternative version (for the dvf/cvf style
of checking low bit set):

call gen_tables(transfer((/2,5,8,17/),(/.FALSE./)))

with a few compilers:

Output for: call gen_tables(transfer((/0,2,0,4/),(/.FALSE./)))
#################################################################
C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>df
/stand:f95 tr
uth_tables
Compaq Visual Fortran Optimizing Compiler Version 6.6 (Update C)
Copyright 2003 Compaq Computer Corp. All rights reserved.

truth_tables
truth_tables.F90(30) : Warning: The field width is too small for the number
of f
ractional digits. [8]


write(*,'(a,4(1x,z8.8)/)') 'Inputs:', transfer(inputs,(/1/))

-----------------------------^
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/subsystem:console
/entry:mainCRTStartup
/debugtype:cv
/pdb:none
C:\DOCUME~1\James\LOCALS~1\Temp\obj1E.tmp
dfor.lib
libc.lib
dfconsol.lib
dfport.lib
kernel32.lib
/out:truth_tables.exe

C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>truth_tables


Inputs: 00000000 00000002 00000000 00000004

NOT
----------------------
A Result
.FALSE. .TRUE.

.FALSE. .TRUE.

.AND.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.

.FALSE. .FALSE. .FALSE.
.FALSE. .FALSE. .FALSE.
.FALSE. .FALSE. .FALSE.

.OR.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.

.FALSE. .FALSE. .FALSE.
.FALSE. .FALSE. .FALSE.
.FALSE. .FALSE. .FALSE.

.EQV.
---------------------------------
A B Result
.FALSE. .FALSE. .TRUE.

.FALSE. .FALSE. .TRUE.
.FALSE. .FALSE. .TRUE.
.FALSE. .FALSE. .TRUE.

.NEQV.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.

.FALSE. .FALSE. .FALSE.
.FALSE. .FALSE. .FALSE.
.FALSE. .FALSE. .FALSE.
#################################################################
Output for: call gen_tables(transfer((/2,5,8,17/),(/.FALSE./)))
#################################################################
C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>df
/stand:f95 tr
uth_tables
Compaq Visual Fortran Optimizing Compiler Version 6.6 (Update C)
Copyright 2003 Compaq Computer Corp. All rights reserved.

truth_tables
truth_tables.F90(30) : Warning: The field width is too small for the number
of f
ractional digits. [8]


write(*,'(a,4(1x,z8.8)/)') 'Inputs:', transfer(inputs,(/1/))

-----------------------------^
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/subsystem:console
/entry:mainCRTStartup
/debugtype:cv
/pdb:none
C:\DOCUME~1\James\LOCALS~1\Temp\obj28.tmp
dfor.lib
libc.lib
dfconsol.lib
dfport.lib
kernel32.lib
/out:truth_tables.exe

C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>truth_tables
Inputs: 00000002 00000005 00000008 00000011

NOT
----------------------
A Result
.FALSE. .TRUE.

.TRUE. .FALSE.

.AND.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE.

.TRUE. .TRUE. .TRUE.

.OR.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

.EQV.
---------------------------------
A B Result
.FALSE. .FALSE. .TRUE.

.FALSE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE.

.TRUE. .TRUE. .TRUE.

.NEQV.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.

.TRUE. .TRUE. .FALSE.
#################################################################

Output for: call gen_tables(transfer((/0,2,0,4/),(/.FALSE./)))
#################################################################
C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>g95 -v
Using built-in specs.
Target:
Configured with:
/src/G95/gcc-4.0-20060302/configure --with-gcc --with-gnu-ld --
with-ld=/mingw/bin/ld --with-gnu-as --with-as=/mingw/bin/as --host=mingw32 --tar
get=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable-languages=c
--disable-win32-registry --disable-shared --without-x --disable-libmudflap --dis
able-libssp
Thread model: win32
gcc version 4.0.3 (g95 0.91!) Nov 15 2006

C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>g95 -std=f95
tru
th_tables.f90 -otruth_tables

C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>truth_tables
Inputs: 00000000 00000001 00000000 00000001

NOT
----------------------
A Result
.FALSE. .TRUE.

.TRUE. .FALSE.

.AND.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE.

.TRUE. .TRUE. .TRUE.

.OR.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

.EQV.
---------------------------------
A B Result
.FALSE. .FALSE. .TRUE.

.FALSE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE.

.TRUE. .TRUE. .TRUE.

.NEQV.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.

.TRUE. .TRUE. .FALSE.
#################################################################
Output for: call gen_tables(transfer((/2,5,8,17/),(/.FALSE./)))
#################################################################
C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>g95 -std=f95
tru
th_tables.f90 -otruth_tables

C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>truth_tables
Inputs: 00000001 00000001 00000001 00000001

NOT
----------------------
A Result
.TRUE. .FALSE.
.TRUE. .FALSE.

.AND.
---------------------------------
A B Result

.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.

.OR.
---------------------------------
A B Result

.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.

.EQV.
---------------------------------
A B Result

.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.

.NEQV.
---------------------------------
A B Result

.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .FALSE.
#################################################################

Output for: call gen_tables(transfer((/0,2,0,4/),(/.FALSE./)))
#################################################################


C:\Program Files\Microsoft Visual

Studio\James\clf\truth_tables>lf95 -f95 -nconc
c -dal truth_tables.f90
Lahey/Fujitsu Fortran 95 Express Release 7.10.02 S/N: XXXXXXXXXXXXXXX
Copyright (C) 1994-2004 Lahey Computer Systems. All rights reserved.
Copyright (C) 1998-2004 FUJITSU LIMITED. All rights reserved.
Compiling file truth_tables.f90.
Compiling program unit funcs at line 1:
Compiling program unit truth_tables at line 62:
Encountered 0 errors, 0 warnings in file truth_tables.f90.
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>truth_tables


Inputs: 00000000 00000002 00000000 00000004

NOT
----------------------
A Result
.FALSE. .TRUE.
.TRUE. .TRUE.

.AND.


---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE.
.TRUE. .TRUE. .FALSE.

.OR.


---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

.EQV.
---------------------------------
A B Result
.FALSE. .FALSE. .TRUE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

.NEQV.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

#################################################################
Output for: call gen_tables(transfer((/2,5,8,17/),(/.FALSE./)))
#################################################################


C:\Program Files\Microsoft Visual

Studio\James\clf\truth_tables>lf95 -f95 -nconc
c -dal truth_tables.f90
Lahey/Fujitsu Fortran 95 Express Release 7.10.02 S/N: XXXXXXXXXXXXXXX
Copyright (C) 1994-2004 Lahey Computer Systems. All rights reserved.
Copyright (C) 1998-2004 FUJITSU LIMITED. All rights reserved.
Compiling file truth_tables.f90.
Compiling program unit funcs at line 1:
Compiling program unit truth_tables at line 62:
Encountered 0 errors, 0 warnings in file truth_tables.f90.
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>truth_tables
Inputs: 00000002 00000005 00000008 00000011

NOT
----------------------
A Result
.TRUE. .TRUE.
.TRUE. .TRUE.

.AND.
---------------------------------
A B Result

.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .TRUE.

.OR.
---------------------------------
A B Result

.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.

.EQV.
---------------------------------
A B Result

.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.

.NEQV.
---------------------------------
A B Result

.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
#################################################################

Output for: call gen_tables(transfer((/0,2,0,4/),(/.FALSE./)))
#################################################################
C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>ftn95
truth_tabl
es.f90 /link
[FTN95/Win32 Ver. 4.9.0 Copyright (C) Silverforst Ltd 1993-2005]
PROCESSING MODULE [<FUNCS> FTN95/Win32 v4.9.0]
NO ERRORS [<PRINT_TABLE> FTN95/Win32 v4.9.0]
NO ERRORS [<PRINT_NOT> FTN95/Win32 v4.9.0]
NO ERRORS [<GEN_TABLES> FTN95/Win32 v4.9.0]
NO ERRORS [<FUNCS> FTN95/Win32 v4.9.0]
NO ERRORS [<TRUTH_TABLES> FTN95/Win32 v4.9.0]
Creating executable: truth_tables.EXE

C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>truth_tables


Inputs: 00000000 00000002 00000000 00000004

NOT
----------------------
A Result
.FALSE. .TRUE.

.TRUE. .FALSE.

.AND.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE.
.TRUE. .TRUE. .FALSE.

.OR.


---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

.EQV.
---------------------------------
A B Result
.FALSE. .FALSE. .TRUE.

.FALSE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE.
.TRUE. .TRUE. .FALSE.

.NEQV.


---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

#################################################################
Output for: call gen_tables(transfer((/2,5,8,17/),(/.FALSE./)))
#################################################################
C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>ftn95
truth_tabl
es.f90 /link
[FTN95/Win32 Ver. 4.9.0 Copyright (C) Silverforst Ltd 1993-2005]
PROCESSING MODULE [<FUNCS> FTN95/Win32 v4.9.0]
NO ERRORS [<PRINT_TABLE> FTN95/Win32 v4.9.0]
NO ERRORS [<PRINT_NOT> FTN95/Win32 v4.9.0]
NO ERRORS [<GEN_TABLES> FTN95/Win32 v4.9.0]
NO ERRORS [<FUNCS> FTN95/Win32 v4.9.0]
NO ERRORS [<TRUTH_TABLES> FTN95/Win32 v4.9.0]
Creating executable: truth_tables.EXE

C:\Program Files\Microsoft Visual Studio\James\clf\truth_tables>truth_tables
Inputs: 00000002 00000005 00000008 00000011

NOT
----------------------
A Result
.TRUE. .FALSE.
.TRUE. .FALSE.

.AND.
---------------------------------
A B Result

.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .TRUE.

.OR.
---------------------------------
A B Result

.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.

.EQV.
---------------------------------
A B Result
.TRUE. .TRUE. .FALSE.

.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .FALSE.
.TRUE. .TRUE. .FALSE.

.NEQV.
---------------------------------
A B Result

.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
.TRUE. .TRUE. .TRUE.
#################################################################

So it can be seen that all the above compilers save CVF attempt to
use masking as well as C internal representation. Evidently C
programmers are less confused by replacement of .NOT. with ~ instead
of !, .AND. with & instead of &&, .OR. with | instead of ||, and
.NEQV. with ^ than they would be by replacing TRANSFER(2,.FALSE.)
with .FALSE. instead of .TRUE. .

It may seem that g95 is preserving syllogisms instead of masking,
but careful inspection shows that it's just a bug in TRANSFER with
literal input. Here is a test program to flesh out what g95 really
thinks it's doing:

C:\g95_MINGW\clf\transfer_copy>type transfer_copy.f90
! File: transfer_copy.f90


! Public domain 2007 James Van Buskirk
module funcs
implicit none
contains

function f(x)
logical, intent(in) :: x(4)
integer f(4)

f = transfer(x,f)
end function f
end module funcs

program transfer_copy
use funcs
implicit none
integer, parameter :: iarray(4) = (/0,1,2,3/)

write(*,*) iarray
write(*,*) transfer(transfer(iarray,(/.FALSE./)),iarray)
write(*,*) f(transfer(iarray,(/.FALSE./)))
write(*,*) f(transfer((/0,1,2,3/),(/.FALSE./)))
write(*,*) transfer(transfer((/0,1,2,3/),(/.FALSE./)),iarray)
end program transfer_copy
! End of file: transfer_copy.f90

C:\g95_MINGW\clf\transfer_copy>g95 -std=f95
transfer_copy.f90 -otransfer_copy

C:\g95_MINGW\clf\transfer_copy>transfer_copy
0 1 2 3
0 1 2 3
0 1 2 3
0 1 1 1
0 1 1 1

Now we can see that the bug is triggered by literal, but not
constant, input. Given this information we can rewrite
truth_tables.f90 so as to settle Andy's hash as follows:

C:\g95_MINGW\clf\transfer_copy>type truth_tables.f90

! integer, parameter :: i(4) = (/2,5,8,17/)
integer, parameter :: i(4) = (/0,2,0,4/)

call gen_tables(transfer(i,(/.FALSE./)))
end program truth_tables

! End of file: truth_tables.f90

C:\g95_MINGW\clf\transfer_copy>g95 -std=f95 truth_tables.f90 -otruth_tables

C:\g95_MINGW\clf\transfer_copy>truth_tables


Inputs: 00000000 00000002 00000000 00000004

NOT
----------------------
A Result
.FALSE. .TRUE.

.TRUE. .FALSE.

.AND.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE.
.TRUE. .TRUE. .FALSE.

.OR.


---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

.EQV.
---------------------------------
A B Result
.FALSE. .FALSE. .TRUE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

.NEQV.
---------------------------------
A B Result
.FALSE. .FALSE. .FALSE.
.FALSE. .TRUE. .TRUE.
.TRUE. .FALSE. .TRUE.
.TRUE. .TRUE. .TRUE.

I repeat that I believe that attempting to use the C internal
representation for Fortran LOGICAL values is inconsistent even
with C usage for logical operators for all the compilers above
that do so, and that keying on a single bit, as CVF does, is
the only way to preserve syllogisms and masking. I hope you
enjoyed my examples above.

Wade Ward

未读,
2007年7月2日 16:18:212007/7/2
收件人

"robin" <rob...@bigpond.com> wrote in message
news:7U7ii.2254$4A1....@news-server.bigpond.net.au...
Then Result tests whether two boolean values are the same.
--
WW


robin

未读,
2007年7月3日 07:56:432007/7/3
收件人
"James Giles" <james...@worldnet.att.net> wrote in message
news:PyEfi.220063$p47.1...@bgtnsc04-news.ops.worldnet.att.net...

> Three: the standard conforming methods of preempting overflow
> are slow, cumbersome, and bulky.

I think that it depends on the operation.
If it's addition/subtraction, it's certainly neither cumbersome nor bulky,
even if it is a little slower. The extra time probably
wouldn't be noticeable for most programs.

Multiplication would be somewhat slower, but not bulky.

Integer division is, of course, unaffected.

robin

未读,
2007年7月3日 07:56:412007/7/3
收件人
"James Giles" <james...@worldnet.att.net> wrote in message
news:kjgfi.113849$Sa4....@bgtnsc05-news.ops.worldnet.att.net...

> Yes 1's complement wraps. Also, 2's complement wraps.
> And, unsigned integers wrap. In all cases the successor of
> the largest value is the least value and the predecessor of
> the least value is the largest value. That's what it means to
> wrap.

I don't call that "wrapping".


robin

未读,
2007年7月3日 07:56:422007/7/3
收件人
"James Van Buskirk" <not_...@comcast.net> wrote in message
news:Mb6dnVaCcYTyyRTb...@comcast.com...

> "robin" <rob...@bigpond.com> wrote in message
> news:6U7ii.2252$4A1....@news-server.bigpond.net.au...

[code & results deleted]

> >> .TRUE. .TRUE. .TRUE.
>
> > What is this supposed to show?
>
> That ifort no longer supports syllogisms.
>
> > Will any Fortran compiler produce the correct values with this code?
>
> Since I had my old Athlon running anyhow, I tried but the version
> as quoted above and an alternative version (for the dvf/cvf style
> of checking low bit set):

That wasn't the answer to my question.
The fact that the code doesn't produce the correct results
on a current compilers indicates that the usages are not valid.


正在加载更多帖子。
0 个新帖子