17

What is the idiomatic way to go Double -> Float?

Is it uncurry encodeFloat . decodeFloat ?

(I am using gloss, this requires Floats)

And what is the recommended way to find an answer to such questions?

I was trying this hoogle query but the answers are all very unhelpful (try it - it has unsafeCoerce at the top of the list)

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
d8d0d65b3f7cf42
  • 2,597
  • 15
  • 28
  • 2
    That is going to be a painful conversion. – Shoe May 04 '15 at 11:59
  • @Jefffrey: are you saying that any such conversion would be painful, or that particular implementation is? – d8d0d65b3f7cf42 May 04 '15 at 12:29
  • I'm not sure, because I remember `Float` being "special" in Haskell, and I remember being told to avoid it like the plague, but in general "double" means double precision floating point number, and it's generally 64 bits, while "float" is a single precision floating point number, which is generally 32 bits. You can clearly see that it's a loss conversion if that's the case. – Shoe May 04 '15 at 12:41
  • @Jefffrey : loss does not matter here as it's just screen coordinates – d8d0d65b3f7cf42 May 04 '15 at 12:43

1 Answers1

22

Use realToFrac :: (Real a, Fractional b) => a -> b.

It converts from any real number type (like Int, Float or Double) to any fractional type (like Float, Double or Rational).

Note that even though the general definition of this function (fromRational . toRational) does a slow conversion via the Rational type, there are rewrite rules which use more efficient implementations for conversions between Float and Double.

hammar
  • 138,522
  • 17
  • 304
  • 385
  • That's the standard way. Should be noted though that the direct implementation is pretty inefficient, since it uses `Rational` as an intermediate. This could certainly be optimised away, but I'm not sure how reliable GHC does this – couldn't find an according `SPECIALIZE`ation in the code. – leftaroundabout May 04 '15 at 12:45
  • 1
    @leftaroundabout: [Found them](https://hackage.haskell.org/package/base-4.8.0.0/docs/src/GHC-Float.html#line-1082). They are implemented as rewrite rules, in this case to `GHC.Float.float2Double`, which is just a wrapper around the `float2Double#` primitive. – hammar May 04 '15 at 12:52
  • still wondering .. why does hoogle not find this `realToFrac`? – d8d0d65b3f7cf42 May 05 '15 at 13:38
  • @d8d0d65b3f7cf42: It does return it about 50 items down the list. It looks like it might not be taking instances into account when ranking the results, however, as it's giving similar rankings to e.g. `fromIntegral` even though there is no `Integral` instance for `Double`. – hammar May 05 '15 at 13:57