Help us understand the problem. What is going on with this article?

Julia の print の丸め処理がおかしい?

More than 1 year has passed since last update.

Float 結合則不成立

浮動小数点数では一般に結合則は成り立ちません。つまり、
(a + b) + c /= a + (b + c)
となります。

IEEE754 の倍精度では仮数部が 53bit 分の情報をもつので、2^53 を超えると浮動小数点数では数直線の刻み幅が 2 になって、1 足しただけでは増えなくなります。

i = 2^53
9007199254740992

x = 1.0 * i
9.007199254740992e15

i + 1 + 1
9007199254740994

Int(x + 1 + 1)
9007199254740992

Int((x + 1) + 1)
9007199254740992

Int(x + (1 + 1))
9007199254740994

当然 3 を足しても段を上がれないのかと思うかもしれませんが、IEEE754 の場合偶数丸めがあるので、奇数1個飛び毎に段を上がれたり上がれなかったりします。

for k = 0:10
    println(k, " ", Int(x + k))c
end

0 9007199254740992
1 9007199254740992
2 9007199254740994
3 9007199254740996
4 9007199254740996
5 9007199254740996
6 9007199254740998
7 9007199254741000
8 9007199254741000
9 9007199254741000
10 9007199254741002

generic 関数の場合、同じ関数に整数と浮動小数点数を引数に与えると結果が違ってくるので、ぱっと見変にみえます。

function f(x)
    Int(x + 1 + 1)
end

f(i + 0)
9007199254740994

f(i + 0.)
9007199254740992

Julia では 1 + 1 の定数部分を最適化して 2 にせずに、式の通りに真面目に計算しているようです。

個人的に浮動小数点数では generic は色々無理がありすぎるだろうと思うのですが、次々期 Fortran で入りそうな勢いです。

デフォルトの print の丸めがおかしい

2^54 からは、数直線上の刻み幅が 4 になります。以下では Float64 の 2^54 に 4.0 を足していってますが、print/println で正しく丸められていないように見えます。もしくは謎な仕様になっています。整数化するとちゃんと表示されていますので、表示の print/println 関数内部の問題だと思われます。

v = 2^54 + 4 + 0.
for k = 0:10
    println(Int(v), "  ", v)
    v = v + 4
end

18014398509481988  1.8014398509481988e16
18014398509481992  1.801439850948199e16
18014398509481996  1.8014398509481996e16
18014398509482000  1.8014398509482e16
18014398509482004  1.8014398509482004e16
18014398509482008  1.801439850948201e16
18014398509482012  1.8014398509482012e16
18014398509482016  1.8014398509482016e16
18014398509482020  1.801439850948202e16
18014398509482024  1.8014398509482024e16
18014398509482028  1.8014398509482028e16
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away