Prevent computations in float16 in scalar and elemwise

Also add a bunch of tests
The think is that we only want to do that if we call self.nfunc, and it is a numpy.ufunc, and I don't think we have that information in make_thunk.
We could maybe do that in make_node, but it would mean storing dtype-specific information as a member.