Float[] * Real is a Float[]?
Basile B.
b2.temp at gmx.com
Wed Dec 11 18:48:58 UTC 2019
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
More information about the Digitalmars-d
mailing list