doubleを整数に変換したい(バイトコード的な意味で)
IEE 754倍精度浮動小数をバイト列にエンコードしたい。Cとかなら簡単に変換できるのだけども、OCamlでやる方法が分らない。
union { long n[2]; double f; } x; x.f = 42.0; // x.n[0]とx.n[1]がエンコードされたやつ
ちゃんと仮数部と指数部を抜きだして、ごにょごにょすればいけるだろうけど、Cで数行のコードをあんまり書きたくないなぁ、と思って。Cのコードをリンクするのも手だけれども、やりかたがよくわからなかった。
追記
id:llaさんに教えてもらいました。
open Obj let of_float (n:float) = let n = repr n in (obj (field n 0):int),(obj (field n 1):int)
たしかに非常にそれっぽいんですが、ちょっと違う気がします。
たとえば、0.75は0x3FE80000 00000000のはずなのですが、これでは違う値がでてきます。
# of_float 0.75; - : int * int = (536084480, 0) # Printf.sprintf "%x" 536084480;; - : string = "1ff40000"
追記 その2
fieldで取得したやつは、1ビットずれているそうです。
# Printf.sprintf "%x" (536084480 lsr 1);; - : string = "3fe80000"
id:MaDさんに、標準ライブラリのInt64モジュールにあると教えてもらいました。
# let n = Int64.bits_of_float 0.75;; val n : int64 = 4604930618986332160L # Printf.sprintf "%Lx" n;; - : string = "3fe8000000000000"
お二人ともありがとうございます。これでなんとかなりそうです。