CTFE pow()

Iain Buclaw via Digitalmars-d digitalmars-d at puremagic.com
Fri Jan 2 06:09:51 PST 2015


On 2 January 2015 at 13:33, Don via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On Friday, 2 January 2015 at 08:52:47 UTC, Daniel Murphy wrote:
>>
>> "Xinok"  wrote in message news:pbjttgrpwhsffoovpida at forum.dlang.org...
>>
>>> I'm wondering if there's any added benefit to implementing these as
>>> intrinsic functions instead? In this way, implementing them in CTFE should
>>> be trivial and the extra knowledge given to the compiler could enable extra
>>> optimizations that wouldn't be possible otherwise. For example, the compiler
>>> understands multiplication and division so, in certain cases, it can replace
>>> these operations with bit-shifting which is faster.
>>
>>
>> I was just about to suggest this.  Another easy way might be to just add
>> get/set mantissa/exponent intrinsics and use those in the ctfe versions.
>
>
> Right. The problem with allowing casts between integers and floating point,
> is that then someone can create a pointer to some of the bits of the float.
> And that's a can of worms. It enables behaviour that is both complicated,
> and useless.
>
> BTW in the existing CTFE you can cast int <-> float and long <-> double.
>
> So you can implement pow for 64 bit floats already. It's only 80-bit reals
> that are a problem, because there is no integer type that is large enough.
> So it's really an X86-specific problem.
>
> I did suggest allowing the specific casts for getting and setting the
> exponent and significand, eg:
>
> ushort exponent = (cast(ushort *)cast(void*)&f)[4];
> ulong significand = *(cast(ulong *)cast(void *)&f);
>
> which would give you everything you need. It's really an intrinsic with very
> very ugly syntax.
> But Iain was pretty unhappy with that idea, IIRC. I think treatment of real
> is very difficult for GDC already.

Getting is fine, setting is the bigger problem, especially when
optimisations come into play.

There was a more complex equivalent of:

double x = 2.0;
ushort *i = cast(ushort *)&x;
i[3] = 0;

That led to this [1] being done instead, before I switched over to
using unions to satisfy @nogc and aliasing under optimisations.

[1]: https://github.com/D-Programming-Language/phobos/commit/df5dab4a7af7aa441e92538876df13c0bb45cda3#diff-8b9f1870415268a4c40b628d596dc405R3100

Iain.


More information about the Digitalmars-d mailing list