www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Float[] * Real is a Float[]?

reply Jonathan Levi <catanscout gmail.com> writes:
Why does this not work?


     float[3] a = [10,2,4];
     real b = 5.5;
     real[3] c;
     c[] = a[]*b;

Is this intentional or a but?  Why is a[]*b a float array and not 
a real array?
Dec 10 2019
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 10 December 2019 at 19:22:01 UTC, Jonathan Levi wrote:
 Why does this not work?
The [] operators work in place. It doesn't create a new array, just multiplies the existing elements.
Dec 10 2019
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/10/19 11:26 AM, Adam D. Ruppe wrote:
 On Tuesday, 10 December 2019 at 19:22:01 UTC, Jonathan Levi wrote:
 Why does this not work?
The [] operators work in place. It doesn't create a new array, just multiplies the existing elements.
Then the a[]*r syntax should not be allowed. We should be forced to write a[] *= r; No? Ali
Dec 10 2019
parent reply kinke <noone nowhere.com> writes:
On Tuesday, 10 December 2019 at 20:35:26 UTC, Ali Çehreli wrote:
 On 12/10/19 11:26 AM, Adam D. Ruppe wrote:
 On Tuesday, 10 December 2019 at 19:22:01 UTC, Jonathan Levi 
 wrote:
 Why does this not work?
The [] operators work in place. It doesn't create a new array, just multiplies the existing elements.
Then the a[]*r syntax should not be allowed. We should be forced to write a[] *= r; No?
No, because the statement is not correct: void main() { float[3] a = [10,2,4]; real b = 5.5; float[3] c = a[] * b; assert(a[0] == 10); // fine, `a` is untouched } The actual reason can be seen by inspecting the lowered AST (-vcg-ast): float[3] c = arrayOp(c[], a[], cast(float)b); or alternatively, by inspecting the LLVM IR produced by LDC, or the assembly: pure nothrow nogc trusted float[] core.internal.arrayop.arrayOp!(float[], float[], float, "*", "=").arrayOp(float[], float[], float) I.e., the array-op is in single precision and the scalar rhs b is cast to a float.
Dec 10 2019
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 10 December 2019 at 20:47:16 UTC, kinke wrote:
 No, because the statement is not correct:
oh yikes sorry about that, the static array is OK because there's already destination memory, I got stuck in my assumption about other slices where it is illegal.
Dec 10 2019
prev sibling parent reply Jab <jab_293 gmall.com> writes:
On Tuesday, 10 December 2019 at 20:47:16 UTC, kinke wrote:
 On Tuesday, 10 December 2019 at 20:35:26 UTC, Ali Çehreli wrote:
 On 12/10/19 11:26 AM, Adam D. Ruppe wrote:
 On Tuesday, 10 December 2019 at 19:22:01 UTC, Jonathan Levi 
 wrote:
 Why does this not work?
The [] operators work in place. It doesn't create a new array, just multiplies the existing elements.
Then the a[]*r syntax should not be allowed. We should be forced to write a[] *= r; No?
No, because the statement is not correct: void main() { float[3] a = [10,2,4]; real b = 5.5; float[3] c = a[] * b; assert(a[0] == 10); // fine, `a` is untouched } The actual reason can be seen by inspecting the lowered AST (-vcg-ast): float[3] c = arrayOp(c[], a[], cast(float)b); or alternatively, by inspecting the LLVM IR produced by LDC, or the assembly: pure nothrow nogc trusted float[] core.internal.arrayop.arrayOp!(float[], float[], float, "*", "=").arrayOp(float[], float[], float) I.e., the array-op is in single precision and the scalar rhs b is cast to a float.
Still doesn't really make sense. The compiler is explicitly giving those types, it seems to be a bug. typeof(float * real) == real That shouldn't be different for arrays, if it should be different for an array then you should have to explicitly cast the real to float.
Dec 10 2019
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Wednesday, 11 December 2019 at 06:27:35 UTC, Jab wrote:
 On Tuesday, 10 December 2019 at 20:47:16 UTC, kinke wrote:
 On Tuesday, 10 December 2019 at 20:35:26 UTC, Ali Çehreli 
 wrote:
 On 12/10/19 11:26 AM, Adam D. Ruppe wrote:
 On Tuesday, 10 December 2019 at 19:22:01 UTC, Jonathan Levi 
 wrote:
 Why does this not work?
The [] operators work in place. It doesn't create a new array, just multiplies the existing elements.
Then the a[]*r syntax should not be allowed. We should be forced to write a[] *= r; No?
No, because the statement is not correct: void main() { float[3] a = [10,2,4]; real b = 5.5; float[3] c = a[] * b; assert(a[0] == 10); // fine, `a` is untouched } The actual reason can be seen by inspecting the lowered AST (-vcg-ast): float[3] c = arrayOp(c[], a[], cast(float)b); or alternatively, by inspecting the LLVM IR produced by LDC, or the assembly: pure nothrow nogc trusted float[] core.internal.arrayop.arrayOp!(float[], float[], float, "*", "=").arrayOp(float[], float[], float) I.e., the array-op is in single precision and the scalar rhs b is cast to a float.
Still doesn't really make sense. The compiler is explicitly giving those types, it seems to be a bug. typeof(float * real) == real That shouldn't be different for arrays, if it should be different for an array then you should have to explicitly cast the real to float.
D allows implicit (and truncating) coercion from 80 bit float to 64 or 32 bits and from 80 or 64 to 32. I once made a PR proposing to disallow them but it's a disruptive change [1]. Because of that if you don't take care the D code for floating-point maths will be full of `cvtd2ss` instructions with possible precision loss. [1]: https://issues.dlang.org/show_bug.cgi?id=17933
Dec 11 2019
prev sibling parent kinke <noone nowhere.com> writes:
On Wednesday, 11 December 2019 at 06:27:35 UTC, Jab wrote:
 Still doesn't really make sense. The compiler is explicitly 
 giving those types, it seems to be a bug.

 typeof(float * real) == real

 That shouldn't be different for arrays, if it should be 
 different for an array then you should have to explicitly cast 
 the real to float.
I guess that's a legitimate point. As long as the druntime array-op implementation is already prepared for such flexibility in used input and output types, the compiler could be adapted accordingly. - Mixing types probably hurts vectorizability though.
Dec 11 2019