On 18 November 2012 14:13, Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
11/18/2012 3:21 PM, Manu пишет:
I've often wondered about having an official 'half' type.
It's very common in rendering/image processing, supported by most video
cards (so compression routines interacting with this type are common),
and it's also supported in hardware by some cpu's.

ARM for instance supports 'half's in hardware, and GCC has an __fp16
type which would map nicely if D supported the type in the front end.

The alternative us to use ushort everywhere, which is awkward, because
it is neither unsigned, nor is it an integer, and it's not typesafe
(allows direct assignment to ints and stuff)...
It would be nice if: cast(half)someFloat would yield the proper value,
even if it is performed in software in most architectures, it could be
mapped to hardware for those that do it.

I guess half(someFloat) will do for conversion.

How do you define 'will do'? It still behaves differently than proper types.
someFloat = someDouble without a cast is a compile error, likewise should be true in this case, but I don't know how to do that.
someHalf = someFloat should require an explicit cast too, or use a 1.0h literal ;)

It could be done in a library, but then GCC couldn't map it properly to
the hardware type, and since D has no way to describe implicit casts
(that I know of?) it becomes awkward to use.

alias this should work.
Just tried it, works wonders:

import std.math;

struct half{
    ushort data; //this one should be __fp16 where it works
//other overloaded ops, etc.

    alias getFloat this;
    //***only for the purpose of showing implicit conversion ***
    float getFloat(){ return data * 0.1; }
}

void main(){
    float x = half(12);
    assert(abs(x - 1.2) < 1e-6);

}

Yup, that solves the up-cast problem perfectly! I didn't think of that trick.

someFloat = someHalf <- doesn't work, because a cast operator expects an
explicit cast, even though this is a lossless conversion and should be
exactly the same as someDouble = someFloat.

Thoughts?

Everything but hardware support is doable as is. I'm not sure if it's possible and/or feasible to make _efficient_ wrapper type that uses hardware support.

The easiest path seems to be:
- convince GDC to add __fp16 type as an extension that maps to GCC's one
- use it on GDC, and fallback to emulation on DMD

That being said I personally have no objections to add half type to built-ins in DMD.

I'm sure it's already accessible in GDC, but it's not portable unless it gets a proper name in the front end.
The point would be to name the type, add the conversion functions to druntime for fallback/portability, and a literal 1.0h would be handy to identify the type to templates.