|
|
|
|
|
March 27th, 2004, 02:49 AM
|
|
Lieutenant General
|
|
Join Date: Mar 2004
Location: Albuquerque New Mexico
Posts: 2,997
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Re: Best (CD Bootable?) Linux Distro for Dominions?
[quote] alexti:
[QB]I'm curious. Is it possible to fix Johan's problem with just grouping by parenthesises? How would you rewrite the expression for that? [\qb]
Well, if "It was something about the windows compiler not doing math formulas in quite the same order as generic open OS compilers" then odds are that the use of parathensises, and breaking the formula down into discrete lines of code, would take care of it.
Hard to say how to rewrite the expression without seeing the source code and expression, but the complex multiline statements often used to express formulas are a common source of problems. The C++ standard left a few too many things (like order of evaluation) undefined, meaning that even on the same platform, different compilers give different results. This is even without accounting for compiler inadequacies, where there is currently only one (Comeau / EDG) available that is approximately 100% compliant with the standard. (Last I knew, Comeau didn't support "export" on templates, but then, no one does.)
Another likely culprit, though, would be automatic promotion of floats to doubles - different compilers handle it differently, leading to some wildly disparate results. Again, often best handled through explicit casting, and breaking long statements into short ones, such that intermediate results aren't left to compiler whims.
Anyways - use of parenthesises, and breaking complex lines of code (especially calculation heavy code) down into shorter, simpler, statements makes multiplatform life _much_ easier.
Cainehill (whose Last job involved a lot of graphics, GUIs, and modeling & simulation with the same source on different hardware platforms and OSs)
__________________
Wormwood and wine, and the bitter taste of ashes.
|
March 27th, 2004, 03:21 AM
|
|
General
|
|
Join Date: Nov 2000
Posts: 3,013
Thanks: 17
Thanked 25 Times in 22 Posts
|
|
Re: Best (CD Bootable?) Linux Distro for Dominions?
Quote:
Originally posted by Cainehill:
Well, if "It was something about the windows compiler not doing math formulas in quite the same order as generic open OS compilers" then odds are that the use of parathensises, and breaking the formula down into discrete lines of code, would take care of it.
|
Discrete lines can do it. Parentheses can't. The problem, from what we've been told, was that:
random1().LT.random2();//Let's mix FORTRAN and C because of the HTML rules on the board!
Was evaluated in the opposite order under VC++ (right to left) than GCC (left to right). That kind of statement appeared in the MR checking code, so as soon as a MR check happened, the whole rest of the battle was out of whack.
|
March 27th, 2004, 08:04 AM
|
First Lieutenant
|
|
Join Date: Dec 2003
Location: Calgary, Canada
Posts: 762
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Re: Best (CD Bootable?) Linux Distro for Dominions?
Quote:
Originally posted by Cainehill:
Hard to say how to rewrite the expression without seeing the source code and expression
|
Johan has posted the code that was causing problems. It was like that:
code:
if (n + d6() < m + d6())
and different compilers evaluated left and right subexpressions in a different order.
There was some thread a while ago, where programming contest was suggested. Now we have a good problem:
- how to make the expression produce consistent results (independent on compiler), according to the specified order of function d6 invocation (from left to right or from right to left)?
- can it be done without modifying the expression?
|
March 27th, 2004, 08:54 AM
|
First Lieutenant
|
|
Join Date: Dec 2003
Location: Calgary, Canada
Posts: 762
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Re: Best (CD Bootable?) Linux Distro for Dominions?
Hmm... after thinking a bit, I believe the following will do:
code:
class d6 {
public:
static bool left_to_right;
static int next_id;
int id;
int value;
bool is_random;
d6() { id = next_id++; value = 0; is_random = true; }
d6(const d6& y) { *this = y; }
int realize() const
{
if (is_random)
return value + original_d6();
return value;
}
bool operator<(const d6& y) const
{
int x1, y1;
if ((id < y.id) == left_to_right)
{
x1 = realize();
y1 = y.realize();
}
else
{
y1 = y.realize();
x1 = realize();
}
return (x1 < y1);
}
};
int d6::next_id = 0;
bool d6::left_to_right = true;
d6 operator+(int x, const d6& y)
{
d6 result(y);
result.value += x;
return result;
}
d6 operator+(const d6& y, int x)
{
return x + y;
}
Not that I'm recommending it though
|
March 27th, 2004, 03:53 PM
|
|
Lieutenant General
|
|
Join Date: Mar 2004
Location: Albuquerque New Mexico
Posts: 2,997
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Re: Best (CD Bootable?) Linux Distro for Dominions?
Quote:
Originally posted by alexti:
quote: Originally posted by Cainehill:
Hard to say how to rewrite the expression without seeing the source code and expression
|
Johan has posted the code that was causing problems. It was like that:
code:
if (n + d6() < m + d6())
and different compilers evaluated left and right subexpressions in a different order.
Ah - Graeme is right, parenthesis's wouldn't do it, but it wouldn't be 100% necessary to use discrete lines of code either:
code:
if ((int left = n + d6()) && (int right = m + d6()) && (left < right))
Still not pretty, but each '&&' introduces a sequence point, and the short-circuit boolean rules means that the ones to the right are only executed if the previous one was true. Presuming that d6() returns a value between 1 and 6 (and that n and m are unsigned or otherwise always non-negative values), the first two are true, and the final, real, test is whether left is less than right.
Somewhat ugly, but not as counter-intuitive as using non-stochastic dice rolls.
[ March 27, 2004, 13:54: Message edited by: Cainehill ]
__________________
Wormwood and wine, and the bitter taste of ashes.
|
March 27th, 2004, 04:31 PM
|
First Lieutenant
|
|
Join Date: Dec 2003
Location: Calgary, Canada
Posts: 762
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Re: Best (CD Bootable?) Linux Distro for Dominions?
Quote:
Originally posted by Cainehill:
Somewhat ugly, but not as counter-intuitive as using non-stochastic dice rolls.
|
Actually, if the stochastic dice rolls were ok, there would be no problem. Battle replay is based on recalculating the battle resolution, which requires dice roll to be deterministic. It is not a problem by itself, because the RNG Illwinter is using (and most of RNGs I guess) produces fixed sequence of numbers for a given seed. The problem came out, because additional stochastic element was added by order of subexpression evaluation.
|
March 27th, 2004, 04:35 PM
|
First Lieutenant
|
|
Join Date: Dec 2003
Location: Calgary, Canada
Posts: 762
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Re: Best (CD Bootable?) Linux Distro for Dominions?
Quote:
Originally posted by Cainehill:
code:
if ((int left = n + d6()) && (int right = m + d6()) && (left < right))
|
Can you declare in the "if" expression?
|
March 27th, 2004, 08:09 PM
|
Major General
|
|
Join Date: Jan 2004
Posts: 2,425
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Re: Best (CD Bootable?) Linux Distro for Dominions?
Quote:
Originally posted by alexti:
Can you declare in the "if" expression?
|
I don't think I've ever even thought to try anything so horrendously ugly. My old-style C habits cause me to do all my declaring up top.
Still, that shouldn't matter for the purposes of the solution: Declaring them at the top would still allow the code in question to work.
[ March 27, 2004, 18:10: Message edited by: Norfleet ]
|
March 27th, 2004, 08:32 PM
|
|
Lieutenant General
|
|
Join Date: Mar 2004
Location: Albuquerque New Mexico
Posts: 2,997
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Re: Best (CD Bootable?) Linux Distro for Dominions?
Quote:
Originally posted by Norfleet:
quote: Originally posted by alexti:
Can you declare in the "if" expression?
|
I don't think I've ever even thought to try anything so horrendously ugly. My old-style C habits cause me to do all my declaring up top.
Eh. The benefit of declaring them inside the if statement (or for statement) is that they go out of scope as soon as the if or for is exitted. Keeps you from polluting the namespace with what is, after all, throwaway variables that are only used for a helpful side effect. And you get better locality of reference by declaring variables when used, rather than at the top of a function, unless the variables are relevant through most of the function.
Oh, another reason for not declaring them inside the if or for is that Microsoft's compilers don't give the proper lifetime/scope with the default compiler switches; with the switches set to force proper behavior, you can no longer compile Microsoft's header files. (This may be fixed with the latest .Net compilers.)
__________________
Wormwood and wine, and the bitter taste of ashes.
|
March 27th, 2004, 09:38 PM
|
|
First Lieutenant
|
|
Join Date: Sep 2003
Location: Bordeaux, France
Posts: 794
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Re: Best (CD Bootable?) Linux Distro for Dominions?
Quote:
Originally posted by alexti:
quote: Originally posted by Cainehill:
code:
if ((int left = n + d6()) && (int right = m + d6()) && (left < right))
|
Can you declare in the "if" expression? I believe that's one of the differences between the C and C++ standards (where most people would expect them to be the same). IIRC, it's correct C++, but incorrect C. Of course, many C compilers will accept it, but...
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is On
|
|
|
|
|