Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
November 10, 2011 Strange behaviour of var | ||||
---|---|---|---|---|
| ||||
Hey guys, I've got a problem - I've just written a few lines to approximate PI with the Monte Carlo Method. This is my code: import std.stdio, std.conv, std.string, std.random; void main() { string buf; int n, hits; float x, y, pi; Random rnd; rnd.seed(unpredictableSeed); write("Please enter the number of approximation steps: "); stdin.readln(buf); buf = chomp(buf); if(isNumeric(buf)) { n = parse!int(buf); for(int i = 0; i <= n -1; i++) { x = uniform(0.0f, 1.0f, rnd); y = uniform(0.0f, 1.0f, rnd); if((x*x + y*y) <= 1) { hits++; writeln(hits); //only for debugging } } pi = (hits / n) * 4.f; writeln(pi); } } But the result is always 0 because my var "hits" is set to zero before I try to calculate PI. But why? Please help me. Nice wishes Fabian |
November 10, 2011 Re: Strange behaviour of var | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fabian | 'hits' and 'n' are both integers and hits < n, therefore hits/n = 0
in integer arithmetic.
You need to convert at least one of them to a floating point type,
e.g., with 'cast(double)(hits)/n'.
On 10 November 2011 21:08, Fabian <talk2fab@online.de> wrote:
> Hey guys,
>
> I've got a problem - I've just written a few lines to approximate PI with the Monte Carlo Method.
>
> This is my code:
>
> import std.stdio, std.conv, std.string, std.random;
>
> void main()
> {
> string buf;
> int n, hits;
> float x, y, pi;
>
> Random rnd;
> rnd.seed(unpredictableSeed);
>
> write("Please enter the number of approximation steps: ");
> stdin.readln(buf);
> buf = chomp(buf);
>
> if(isNumeric(buf))
> {
> n = parse!int(buf);
> for(int i = 0; i <= n -1; i++)
> {
> x = uniform(0.0f, 1.0f, rnd);
> y = uniform(0.0f, 1.0f, rnd);
>
> if((x*x + y*y) <= 1)
> {
> hits++;
> writeln(hits); //only for debugging
> }
> }
>
> pi = (hits / n) * 4.f;
> writeln(pi);
> }
> }
>
> But the result is always 0 because my var "hits" is set to zero before I try to calculate PI. But why? Please help me.
>
> Nice wishes
> Fabian
>
|
November 10, 2011 Re: Strange behaviour of var | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Brandt | Thank you - now it works :) |
November 10, 2011 Re: Strange behaviour of var | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fabian | This is not related to your question. I just wanted to point out that it is better to use the normal increment operator in the majority of cases. (I avoid calling it pre-increment, because that name suggests a more complicated semantics than there actually is.) On 11/10/2011 12:08 PM, Fabian wrote: > for(int i = 0; i<= n -1; i++) [...] > hits++; In both of those lines you want to merely increment the value of a variable. The post-increment operator that you have used has a different meaning: "increment this variable but use its previous value in this expression." Since the previous value is ignored in those expressions, it is better to just increment: ++i and ++hist. Semantically cleaner... :) Ali |
November 10, 2011 Re: Strange behaviour of var | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | oh ... I see. Thank you ;) |
November 10, 2011 Re: Strange behaviour of var | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fabian | On 11/10/2011 10:45 PM, Fabian wrote:
> oh ... I see. Thank you ;)
++i is unidiomatic, and if the result is unused it means the same thing as i++. So, I'd actually go with i++. The only reason why one would use ++i is because it is less efficient for C++ iterators, but D does not have that problem at all. This is really not important though.
however, about:
for(int i = 0; i <= n -1; i++){}
this is the way to go (less gotchas if index is a size_t, which it sometimes should)
for(int i = 0; i < n; i++){}
But because this exact construct is so common in C and C++, D has an own syntax for it:
foreach(i;0..n){}
This does exactly the same thing.
Always use foreach for trivial iteration.
|
November 10, 2011 Re: Strange behaviour of var | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | size_t can easily bite you* in the ass: import std.algorithm; void main() { int[] a; int val = max(0, a.length - 1); assert(val > 0); // NG, woops! } * = me That one is easy to catch, but in a complex expression you might have ints and size_t and everything gets converted to unsigned, and then you end up with some value over int.max which is implicitly assigned to an int. :/ |
Copyright © 1999-2021 by the D Language Foundation