Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
December 10, 2019 Float[] * Real is a Float[]? | ||||
---|---|---|---|---|
| ||||
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? |
December 10, 2019 Re: Float[] * Real is a Float[]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan Levi | 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.
|
December 10, 2019 Re: Float[] * Real is a Float[]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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
|
December 10, 2019 Re: Float[] * Real is a Float[]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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. |
December 10, 2019 Re: Float[] * Real is a Float[]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kinke | 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.
|
December 11, 2019 Re: Float[] * Real is a Float[]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to kinke | 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.
|
December 11, 2019 Re: Float[] * Real is a Float[]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jab | 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 |
December 11, 2019 Re: Float[] * Real is a Float[]? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jab | 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.
|
Copyright © 1999-2021 by the D Language Foundation