www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - casting int[] to bool[]

reply "Saaa" <empty needmail.com> writes:
 int[] a = [1,2,3,0];
 int[] aa = [0,1,0,1];
 bool[] b = cast(bool[])a.dup;
 bool[] bb = cast(bool[])aa.dup;
 writefln(a,`-->`,b);
 writefln(aa,`-->`,bb);

--

[1 2 3 0]-->[true false false false true false false false true false false 
false false false false false]
[0 1 0 1]-->[false false false false true false false false false false 
false false true false false false]


Why all this disagreeing? 
Jan 28 2009
next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Thu, Jan 29, 2009 at 10:20 AM, Saaa <empty needmail.com> wrote:
  int[] a = [1,2,3,0];
  int[] aa = [0,1,0,1];
  bool[] b = cast(bool[])a.dup;
  bool[] bb = cast(bool[])aa.dup;
  writefln(a,`-->`,b);
  writefln(aa,`-->`,bb);

 --

 [1 2 3 0]-->[true false false false true false false false true false false
 false false false false false]
 [0 1 0 1]-->[false false false false true false false false false false
 false false true false false false]


 Why all this disagreeing?
bool is 1 byte under the hood. Int is 4 bytes. So what you are seeing is the 4 bytes of each int being treated as 4 separate bools in an ordering determined by the endian-ness of your platform. Casting arrays in this way is generally not a good idea. You need to write a function that makes a fresh bool array out of your int array. --bb
Jan 28 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Jan 28, 2009 at 8:25 PM, Bill Baxter <wbaxter gmail.com> wrote:
 On Thu, Jan 29, 2009 at 10:20 AM, Saaa <empty needmail.com> wrote:
  int[] a = [1,2,3,0];
  int[] aa = [0,1,0,1];
  bool[] b = cast(bool[])a.dup;
  bool[] bb = cast(bool[])aa.dup;
  writefln(a,`-->`,b);
  writefln(aa,`-->`,bb);

 --

 [1 2 3 0]-->[true false false false true false false false true false false
 false false false false false]
 [0 1 0 1]-->[false false false false true false false false false false
 false false true false false false]


 Why all this disagreeing?
bool is 1 byte under the hood. Int is 4 bytes. So what you are seeing is the 4 bytes of each int being treated as 4 separate bools in an ordering determined by the endian-ness of your platform. Casting arrays in this way is generally not a good idea. You need to write a function that makes a fresh bool array out of your int array.
Stop beating me to things when I'm in the middle of typing!
Jan 28 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Thu, Jan 29, 2009 at 10:25 AM, Jarrett Billingsley
<jarrett.billingsley gmail.com> wrote:
 On Wed, Jan 28, 2009 at 8:25 PM, Bill Baxter <wbaxter gmail.com> wrote:
 On Thu, Jan 29, 2009 at 10:20 AM, Saaa <empty needmail.com> wrote:
  int[] a = [1,2,3,0];
  int[] aa = [0,1,0,1];
  bool[] b = cast(bool[])a.dup;
  bool[] bb = cast(bool[])aa.dup;
  writefln(a,`-->`,b);
  writefln(aa,`-->`,bb);

 --

 [1 2 3 0]-->[true false false false true false false false true false false
 false false false false false]
 [0 1 0 1]-->[false false false false true false false false false false
 false false true false false false]


 Why all this disagreeing?
bool is 1 byte under the hood. Int is 4 bytes. So what you are seeing is the 4 bytes of each int being treated as 4 separate bools in an ordering determined by the endian-ness of your platform. Casting arrays in this way is generally not a good idea. You need to write a function that makes a fresh bool array out of your int array.
Stop beating me to things when I'm in the middle of typing!
Heh heh. I sensed this one was gonna be a race. :-P --bb
Jan 28 2009
prev sibling next sibling parent reply "Saaa" <empty needmail.com> writes:
:D

 Casting an expression to bool means testing for 0 or !=0 for arithmetic 
types, and null or !=null for pointers or references.
So a per element bool cast should be safe, right?

That makes my full code like this:

char[][] data;
data=cast(char[][])splitlines(cast(invariant 
char[])read(`data\parsed.dat`));

bool[][] dataIn = new bool[][](data.length, 3);

for(int i; i<data.length; i++)
{
 int[3] temp = to!(int[])(split(data[i][14..19].idup,`,`)); // 14..19 = 
`0,0,1`
 foreach(index, t; temp)
 {
  dataIn[i][index] = cast(bool) t;
 }
}
writefln(data[0][14..19]);
writefln(dataIn[0]);

----------It writes correctly:
0,0,1
[false false true]

Yay, thanks 
Jan 28 2009
next sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Thu, Jan 29, 2009 at 11:10 AM, Saaa <empty needmail.com> wrote:
 :D
  dataIn[i][index] = cast(bool) t;
Jarrett? You want to comment first? :-D --bb
Jan 28 2009
parent reply "Saaa" <empty needmail.com> writes:
Erm, anybody is fine to me..

Is it the naming, still the casting or something else totally?
Jan 28 2009
next sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Thu, Jan 29, 2009 at 11:57 AM, Saaa <empty needmail.com> wrote:
 Erm, anybody is fine to me..

 Is it the naming, still the casting or something else totally?
  dataIn[i][index] = cast(bool) t;
It's just that casting is a very blunt tool and should be avoided whenever possible, because the compiler won't tell you if you're doing something completely crazy. Here you could use somethign like: dataIn[i][index] = (t!=0); instead of casting. --bb
Jan 28 2009
next sibling parent "Saaa" <empty needmail.com> writes:
Ok.
I thought that in this particular case it would be equally safe.
Casting is so easy to read.. I'll try and minimize my usage  ; )

 It's just that casting is a very blunt tool and should be avoided
 whenever possible, because the compiler won't tell you if you're doing
 something completely crazy.

 Here you could use somethign like:

    dataIn[i][index] = (t!=0);

 instead of casting.

 --bb 
Jan 28 2009
prev sibling parent reply "Saaa" <empty needmail.com> writes:
Most of the std.math functions take reals and when I have a float or a 
double I always cast them to real to make it fit.
Should I instead use to! here as well? 
Jan 29 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 2:35 PM, Saaa <empty needmail.com> wrote:
 Most of the std.math functions take reals and when I have a float or a
 double I always cast them to real to make it fit.
 Should I instead use to! here as well?
You don't have to cast anything actually. floats and doubles are implicitly convertible to real. This isn't Pascal.
Jan 29 2009
parent reply "Saaa" <empty needmail.com> writes:
But then I get stuff like this:

value += pow( x, 2); //x=double
--
testcase.d(374): function std.math.pow called with argument types:
 (double,int)
matches both:
 std.math.pow(real x, uint n)
and:
 std.math.pow(real x, int n)
Jan 29 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Saaa wrote:
 But then I get stuff like this:
 
 value += pow( x, 2); //x=double
 --
 testcase.d(374): function std.math.pow called with argument types:
  (double,int)
 matches both:
  std.math.pow(real x, uint n)
 and:
  std.math.pow(real x, int n)
That's because '2' as a literal is both an int and a uint. Try this:
 value += pow( x, 2u );
-- Daniel
Jan 29 2009
parent reply "Saaa" <empty needmail.com> writes:
That gives the same error.. only casting x to real works :/
 That's because '2' as a literal is both an int and a uint.  Try this:

 value += pow( x, 2u );
-- Daniel
Jan 29 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 6:15 PM, Saaa <empty needmail.com> wrote:
 That gives the same error.. only casting x to real works :/
That's more an issue with D's extremely (overly?) strict overload resolution rules. Functions like sin() shouldn't be an issue, since there is only one overload with those. But yes, as far as pow() is concerned, I guess you do have to cast to real. Casting is fine here, don't bother using to!().
Jan 29 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Jarrett Billingsley" wrote
 On Thu, Jan 29, 2009 at 6:15 PM, Saaa <empty needmail.com> wrote:
 That gives the same error.. only casting x to real works :/
That's more an issue with D's extremely (overly?) strict overload resolution rules. Functions like sin() shouldn't be an issue, since there is only one overload with those. But yes, as far as pow() is concerned, I guess you do have to cast to real. Casting is fine here, don't bother using to!().
This is such a common "mistake", and really more of an annoyance, I wonder if it might be better if pow were switched to a template that called the actual pow after casting the first argument to real. Often times, one does not use reals as their variable type, and I seem to recall this kind of error happens even with literals for both arguments... Something like: real pow(T, U)(T t, U u) { return _pow(cast(real)t, u); } -Steve
Jan 29 2009
next sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Fri, Jan 30, 2009 at 10:46 AM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 "Jarrett Billingsley" wrote
 On Thu, Jan 29, 2009 at 6:15 PM, Saaa <empty needmail.com> wrote:
 That gives the same error.. only casting x to real works :/
That's more an issue with D's extremely (overly?) strict overload resolution rules. Functions like sin() shouldn't be an issue, since there is only one overload with those. But yes, as far as pow() is concerned, I guess you do have to cast to real. Casting is fine here, don't bother using to!().
This is such a common "mistake", and really more of an annoyance, I wonder if it might be better if pow were switched to a template that called the actual pow after casting the first argument to real. Often times, one does not use reals as their variable type, and I seem to recall this kind of error happens even with literals for both arguments... Something like: real pow(T, U)(T t, U u) { return _pow(cast(real)t, u); }
You may count me among the annoyed. I never use 'real' for anything, so I get those errors a lot. --bb
Jan 29 2009
parent "Saaa" <empty needmail.com> writes:
Good to see it isn't just me doing something stupid :)

 You may count me among the annoyed.  I never use 'real' for anything,
 so I get those errors a lot.

 --bb 
Jan 29 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 8:46 PM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 This is such a common "mistake", and really more of an annoyance, I wonder
 if it might be better if pow were switched to a template that called the
 actual pow after casting the first argument to real.  Often times, one does
 not use reals as their variable type, and I seem to recall this kind of
 error happens even with literals for both arguments...

 Something like:

 real pow(T, U)(T t, U u)
 {
   return _pow(cast(real)t, u);
 }
That's probably how it'd be written in modern D. Most of std.math is probably 8 years old and pre-templates.
Jan 29 2009
prev sibling parent reply Don <nospam nospam.com> writes:
Steven Schveighoffer wrote:
 "Jarrett Billingsley" wrote
 On Thu, Jan 29, 2009 at 6:15 PM, Saaa <empty needmail.com> wrote:
 That gives the same error.. only casting x to real works :/
That's more an issue with D's extremely (overly?) strict overload resolution rules. Functions like sin() shouldn't be an issue, since there is only one overload with those.
The underlying problem is the implicit conversions. A problem with sin() used to exist: There was sin(creal) and sin(ireal). Then if you have sin(float) there are so many conversion options: float->double -> real \ \ \ cfloat->cdouble-> creal So once you've implemented any two of those functions, you have to implement all of the others. It's really quite ridiculous. I got Walter to remove the implicit conversions real->complex for that reason. But yes, as far as pow() is
 concerned, I guess you do have to cast to real.  Casting is fine here,
 don't bother using to!().
 
 This is such a common "mistake", and really more of an annoyance, I wonder 
 if it might be better if pow were switched to a template that called the 
 actual pow after casting the first argument to real.  Often times, one does 
 not use reals as their variable type, and I seem to recall this kind of 
 error happens even with literals for both arguments...
 
 Something like:
 
 real pow(T, U)(T t, U u)
 {
    return _pow(cast(real)t, u);
 }
 
 -Steve 
 
 
It would be better. Please create a bugzilla report, and I'll fix it.
Jan 30 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Don" wrote
 Steven Schveighoffer wrote:
 This is such a common "mistake", and really more of an annoyance, I 
 wonder if it might be better if pow were switched to a template that 
 called the actual pow after casting the first argument to real.  Often 
 times, one does not use reals as their variable type, and I seem to 
 recall this kind of error happens even with literals for both 
 arguments...

 Something like:

 real pow(T, U)(T t, U u)
 {
    return _pow(cast(real)t, u);
 }

 -Steve
It would be better. Please create a bugzilla report, and I'll fix it.
http://d.puremagic.com/issues/show_bug.cgi?id=2636 BTW, I assigned to the only Don in the list, not sure if that is you... Please fix in Tango as well if you wouldn't mind ;) -Steve
Jan 30 2009
parent Don <nospam nospam.com> writes:
Steven Schveighoffer wrote:
 "Don" wrote
 Steven Schveighoffer wrote:
 This is such a common "mistake", and really more of an annoyance, I 
 wonder if it might be better if pow were switched to a template that 
 called the actual pow after casting the first argument to real.  Often 
 times, one does not use reals as their variable type, and I seem to 
 recall this kind of error happens even with literals for both 
 arguments...

 Something like:

 real pow(T, U)(T t, U u)
 {
    return _pow(cast(real)t, u);
 }

 -Steve
It would be better. Please create a bugzilla report, and I'll fix it.
http://d.puremagic.com/issues/show_bug.cgi?id=2636 BTW, I assigned to the only Don in the list, not sure if that is you...
Yes.
 Please fix in Tango as well if you wouldn't mind ;)
Of course. The Tango, phobos1, and phobos2 math files are a copy & paste of each other, with a few name changes.
 
 -Steve 
 
 
Jan 30 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Jan 28, 2009 at 9:57 PM, Bill Baxter <wbaxter gmail.com> wrote:
 It's just that casting is a very blunt tool and should be avoided
 whenever possible, because the compiler won't tell you if you're doing
 something completely crazy.

 Here you could use somethign like:

    dataIn[i][index] = (t!=0);

 instead of casting.
Blunt? Pfah! cast(bool)int is well-defined. ;)
Jan 28 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Thu, Jan 29, 2009 at 12:04 PM, Jarrett Billingsley
<jarrett.billingsley gmail.com> wrote:
 On Wed, Jan 28, 2009 at 9:57 PM, Bill Baxter <wbaxter gmail.com> wrote:
 It's just that casting is a very blunt tool and should be avoided
 whenever possible, because the compiler won't tell you if you're doing
 something completely crazy.

 Here you could use somethign like:

    dataIn[i][index] = (t!=0);

 instead of casting.
Blunt? Pfah! cast(bool)int is well-defined. ;)
Just you're more likely to catch an error if t changes from being an int to something else later on. I wish D had a "tame and well-behaved casts only please" kind of cast. :-( --bb
Jan 28 2009
prev sibling next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Jan 28, 2009 at 10:07 PM, Bill Baxter <wbaxter gmail.com> wrote:
 Just you're more likely to catch an error if t changes from being an
 int to something else later on.
 I wish D had a "tame and well-behaved casts only please" kind of cast. :-(

 --bb
Ofine. He could use to!(bool) then.
Jan 28 2009
parent reply "Saaa" <empty needmail.com> writes:
 Ofine.  He could use to!(bool) then.
erm... for(int i; i<data.length; i++) { int[60] tempIn = to!(int[])(split(data[i][22..141].idup,`,`)); foreach(index, t; tempIn) { dataIn[i][index] = to!(bool)(t); } } C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(344): Error: cannot implicitly convert expression (value) of type int to bool C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(206): template instance std.conv.toImpl!(int,bool) error instantiating C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(34): template instance std.conv.to!(bool).to!(int) error instantiating
Jan 29 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 10:56 AM, Saaa <empty needmail.com> wrote:
 Ofine.  He could use to!(bool) then.
erm... for(int i; i<data.length; i++) { int[60] tempIn = to!(int[])(split(data[i][22..141].idup,`,`)); foreach(index, t; tempIn) { dataIn[i][index] = to!(bool)(t); } } C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(344): Error: cannot implicitly convert expression (value) of type int to bool C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(206): template instance std.conv.toImpl!(int,bool) error instantiating C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(34): template instance std.conv.to!(bool).to!(int) error instantiating
Well that's stupid. Tango's to!() handles that case. Phobos needs to catch up!
Jan 29 2009
parent reply "Saaa" <empty needmail.com> writes:
Well casting it is then for me, for now.

This way of reading all these booleans is a bit slow... a minute for 700_000 
lines

Is there some way to speed this up?


 Well that's stupid.  Tango's to!() handles that case.  Phobos needs to 
 catch up! 
Jan 29 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 11:28 AM, Saaa <empty needmail.com> wrote:
 Well casting it is then for me, for now.

 This way of reading all these booleans is a bit slow... a minute for 700_000
 lines

 Is there some way to speed this up?
It's probably due to the absurd amount of memory allocation you're causing. Each call to split() allocates an array (whose size is not known in advance, so it requires several appends), and each call to to!(int[]) allocates _another_ array. That's 1.4 million arrays you're allocating, most of which are garbage, and each allocation can potentially trigger a GC cycle. It would be a lot more efficient if you just parsed out the line yourself. auto data = splitlines(read(`data\parsed.dat`).idup); auto dataIn = new bool[][](data.length, 3); foreach(i, line; data) { dataIn[i][0] = line[14] == '1'; dataIn[i][1] = line[16] == '1'; dataIn[i][2] = line[18] == '1'; } Now we perform only a few allocations, all of which are before the loop.
Jan 29 2009
parent reply "Saaa" <empty needmail.com> writes:
 It's probably due to the absurd amount of memory allocation you're
 causing.  Each call to split() allocates an array (whose size is not
 known in advance, so it requires several appends), and each call to
 to!(int[]) allocates _another_ array.  That's 1.4 million arrays
 you're allocating, most of which are garbage, and each allocation can
 potentially trigger a GC cycle.

 It would be a lot more efficient if you just parsed out the line yourself.

 auto data = splitlines(read(`data\parsed.dat`).idup);
 auto dataIn = new bool[][](data.length, 3);

 foreach(i, line; data)
 {
    dataIn[i][0] = line[14] == '1';
    dataIn[i][1] = line[16] == '1';
    dataIn[i][2] = line[18] == '1';
 }

 Now we perform only a few allocations, all of which are before the loop.
Yay massive speedup!! (~2 sec for the loop) Is `bool = x == y` faster than `if ( x == y ) true else false` ? For the 60 large boolean part I used a loop. Not that I really need the extra speedup (if any) but how could I manually unroll that loop? I know you can do things like that in D.. btw. side note: I love slices :D auto sliceIn = dataIn[0..300]; auto sliceOut = dataOut[0..300]; rndGen.seed(1); randomShuffle(sliceIn, rndGen); rndGen.seed(1); randomShuffle(sliceOut, rndGen);
Jan 29 2009
next sibling parent "Saaa" <empty needmail.com> writes:
By manually I mean something between me typing all 60 off them and letting 
the compiler optimize it as such. 
Jan 29 2009
prev sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 1:57 PM, Saaa <empty needmail.com> wrote:

 Yay massive speedup!! (~2 sec for the loop)
 Is `bool = x == y` faster than `if ( x == y ) true else false` ?
No, just shorter to type. They compile down to pretty much the same machine code.
 For the 60 large boolean part I used a loop.
 Not that I really need the extra speedup (if any) but how could I manually
 unroll that loop?
 I know you can do things like that in D..
Oh, so you mean you have 60 bools on each line? You can do that with some templating and string mixin magic: // declare these at global scope template Tuple(T...) { alias T Tuple; } // Generates a tuple of numbers in the range [0, n) template Range(int n) { static if(n == 0) alias Tuple!() Range; else alias Tuple!(Range!(n - 1), n - 1) Range; } // then this is your loop in main foreach(i, line; data) { // this foreach loop is run at compile time foreach(j; Range!(60)) mixin("dataIn[i][" ~ j.stringof ~ "] = line[14 + 2 * " ~ j.stringof ~ "] == '1';"); }
Jan 29 2009
parent reply "Saaa" <empty needmail.com> writes:
This will take some time to understand.
Things I have never used before : D
Tuple, variadic function, template, mixin
.stringof(can't find this one), static if

I'll read up until I understand this.

One question I can ask.
Why is that foreach loop run at compile time?
The compiler checks for a template parameter?

 // declare these at global scope
 template Tuple(T...) { alias T Tuple; }

 // Generates a tuple of numbers in the range [0, n)
 template Range(int n)
 {
    static if(n == 0)
        alias Tuple!() Range;
    else
        alias Tuple!(Range!(n - 1), n - 1) Range;
 }

 // then this is your loop in main
 foreach(i, line; data)
 {
    // this foreach loop is run at compile time
    foreach(j; Range!(60))
        mixin("dataIn[i][" ~ j.stringof ~
            "] = line[14 + 2 * " ~ j.stringof ~ "] == '1';");
 } 
Jan 29 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Saaa wrote:
 This will take some time to understand.
 Things I have never used before : D
 Tuple, variadic function, template, mixin
 ..stringof(can't find this one), static if
 
 I'll read up until I understand this.
 
 One question I can ask.
 Why is that foreach loop run at compile time?
 The compiler checks for a template parameter?
 
 [snip]
Tuples are like arrays that have a fixed length, where each element can be of absolutely any type at all. What this means is that it potentially takes different code to access each element of a tuple. So when you see
 foreach( i ; Range!(4) ) foo(i);
What is actually being generated is this:
 foo(0);
 foo(1);
 foo(2);
 foo(3);
It's not really doing the foreach at compile time, but it is unrolling it. You might think "but why doesn't this happen for arrays?" Because you can't do THIS with arrays:
 foreach( i,x ; Tuple!(0, "b", 3.0) ) writefln("Element %s == %s",i,x);
Which expands to:
 writefln("Element %s == %s",0,0);
 writefln("Element %s == %s",1,"b");
 writefln("Element %s == %s",2,3.0);
-- Daniel
Jan 29 2009
parent "Saaa" <empty needmail.com> writes:
Thanks, that makes sense!
 Tuples are like arrays that have a fixed length, where each element can
 be of absolutely any type at all.

 What this means is that it potentially takes different code to access
 each element of a tuple.  So when you see

 foreach( i ; Range!(4) ) foo(i);
What is actually being generated is this:
 foo(0);
 foo(1);
 foo(2);
 foo(3);
It's not really doing the foreach at compile time, but it is unrolling it. You might think "but why doesn't this happen for arrays?" Because you can't do THIS with arrays:
 foreach( i,x ; Tuple!(0, "b", 3.0) ) writefln("Element %s == %s",i,x);
Which expands to:
 writefln("Element %s == %s",0,0);
 writefln("Element %s == %s",1,"b");
 writefln("Element %s == %s",2,3.0);
-- Daniel
Jan 29 2009
prev sibling parent Brad Roberts <braddr puremagic.com> writes:
Bill Baxter wrote:
 On Thu, Jan 29, 2009 at 12:04 PM, Jarrett Billingsley
 <jarrett.billingsley gmail.com> wrote:
 On Wed, Jan 28, 2009 at 9:57 PM, Bill Baxter <wbaxter gmail.com> wrote:
 It's just that casting is a very blunt tool and should be avoided
 whenever possible, because the compiler won't tell you if you're doing
 something completely crazy.

 Here you could use somethign like:

    dataIn[i][index] = (t!=0);

 instead of casting.
Blunt? Pfah! cast(bool)int is well-defined. ;)
Just you're more likely to catch an error if t changes from being an int to something else later on. I wish D had a "tame and well-behaved casts only please" kind of cast. :-( --bb
Oh, hey, that reminds me.. Walter! When are we going to get the equivalent to const_cast? And the related restriction that cast can't alter constness? I've already made the mistake at least once changing type and constness, without meaning to do the latter, at the same time. Thanks, Brad
Jan 28 2009
prev sibling next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Jan 28, 2009 at 9:10 PM, Saaa <empty needmail.com> wrote:
 char[][] data;
 data=cast(char[][])splitlines(cast(invariant
 char[])read(`data\parsed.dat`));

 bool[][] dataIn = new bool[][](data.length, 3);

 for(int i; i<data.length; i++)
 {
  int[3] temp = to!(int[])(split(data[i][14..19].idup,`,`)); // 14..19 =
 `0,0,1`
  foreach(index, t; temp)
  {
  dataIn[i][index] = cast(bool) t;
  }
 }
 writefln(data[0][14..19]);
 writefln(dataIn[0]);
Sorry, can't help but post this: local data = io.readFile("data/parsed.dat").splitLines().apply$ \line -> line[14 .. 19].split(",").apply$ \item -> toBool$ toInt$ item writeln$ data[0] It's a one-liner (one-..statementer) in MiniD! <_<
Jan 28 2009
parent reply "Saaa" <empty needmail.com> writes:
 Sorry, can't help but post this:

 local data = io.readFile("data/parsed.dat").splitLines().apply$
 \line -> line[14 .. 19].split(",").apply$
 \item -> toBool$ toInt$ item

 writeln$ data[0]

 It's a one-liner (one-..statementer) in MiniD!  <_<
Waa! Can't toInt be skipped when you use the to! template?
Jan 28 2009
parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Jan 28, 2009 at 10:37 PM, Saaa <empty needmail.com> wrote:
 Sorry, can't help but post this:

 local data = io.readFile("data/parsed.dat").splitLines().apply$
 \line -> line[14 .. 19].split(",").apply$
 \item -> toBool$ toInt$ item

 writeln$ data[0]

 It's a one-liner (one-..statementer) in MiniD!  <_<
Waa! Can't toInt be skipped when you use the to! template?
MiniD !is D. There are no templates; toInt and toBool are just functions.
Jan 28 2009
prev sibling parent BCS <none anon.com> writes:
Hello Saaa,

 :D
 
 Casting an expression to bool means testing for 0 or !=0 for
 arithmetic
 types, and null or !=null for pointers or references.
 So a per element bool cast should be safe, right?
cast is an O(1) op in all cases except opCast on UDTs. All array casts just paint an array of the old type over the new.
Jan 28 2009
prev sibling parent Derek Parnell <derek psych.ward> writes:
On Thu, 29 Jan 2009 02:20:08 +0100, Saaa wrote:

  int[] a = [1,2,3,0];
  int[] aa = [0,1,0,1];
  bool[] b = cast(bool[])a.dup;
  bool[] bb = cast(bool[])aa.dup;
  writefln(a,`-->`,b);
  writefln(aa,`-->`,bb);
Casting is not always the same as converting. In this case you are NOT converting an array of ints to an array of bools, instead you are telling the compiler to pretend that the array of ints is really an array of bools.
 [1 2 3 0]-->[true false false false true false false false true false
 false false false false false false]
 [0 1 0 1]-->[false false false false true false false false false
  false false false true false false false]
In each case you have sixteen bools because each of the four ints uses four bytes and is thus is sixteen bytes long. Each byte is interpreted by writefln() as a bool value. If you need to use 'ints' as bool values you have to provide your own conversion routine. For example ... int[] a = [1,2,3,0]; bool[] b; -- Convert to int array to bool array. b.length = a.length; foreach( i, x; a) b[i] = (x != 0); writefln(a,`-->`,b); -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Jan 28 2009