4

GHC をライブラリとして使用して、Haskell から Javascript へのコード ジェネレーターを作成しています。Javascript には整数型がなく、その Number 型は 2⁵³ までの整数しか適切に表現できないため、整数を Number として表現し、2³² を法とするすべての演算を明示的に実行します。これは 32 ビット GHC ではうまく機能しますが、64 ビット版ではかなり悪くなります。

GHC は喜んで Int64 値を Int に変換し、Int 定数を 64 ビット値として解釈します (たとえば、0xffffffff は -1 ではなく 4294967295 になります)。

コンパイラは、標準ライブラリが 32 ビット マシン上に構築されている場合、64 ビット システム上でも「通常の」Web 処理に対して非常にうまく機能しますが、「大きな数字を使用しないでください。OK?」コンパイラのマニュアルで見たいものではありません。問題の一部 (すべてではない) は、-O0 を指定してコンパイルすることで軽減できますが、(当然のことながら) 遅いだけでなく、大きすぎるコードが生成されます。

そのため、GHC が Int と Int64 が同等であると想定しないようにする必要があります。これは可能ですか?

4

3 に答える 3

7

32 ビット GHC を使用しないと、これは不可能です。

Haskell 言語標準ではInt、型について知っている唯一のことは、

少なくとも範囲 [-2^29 .. 2^29-1

Intしたがって、これより大きな値を喜んで切り捨てても、完全に準拠した Haskell 2010 実装にすることができます!

ただし、おそらくこれを行うべきではなく、代わりに JavaScript の 64 ビット整数型を探す必要があります。Int64例えば ​​GHC が32 ビットマシンでサポートするのと同じトリックです。

于 2012-05-08T12:20:06.717 に答える
3

原則として、「Int」は 2^29 が十分に大きい場合にのみ使用する必要があり、それ以外は問題ありません。それ以外の場合は、Integer または Data.Word または Data.Int (Int8、Int16 など) 型のいずれかを使用します。良い例には、ほとんどのサイズと数が含まれます (ただし、最近では 2^32 を簡単に超える可能性があるファイル サイズは含まれません)。

古典的な悪い例: Control.Concurrent.threadDelay :: Int -> IO (). 引数は、休止時間 (uSec) です。2^29 uSec = 8.94784853 分 (Google Calculator による)。引数は整数、または少なくとも Word64 (584 554.531 年) である必要があります。

于 2012-05-08T18:56:44.690 に答える
1

Javascript の数値は double として表現されるため、 を使用しますDouble

于 2012-05-08T16:47:01.070 に答える