JSON処理のコマンドラインツールであるjq
が、5年ぶりにアップデートしました。現在の最新は1.7.1(2023年12月リリース)です。1.6からいろいろと改定や新機能の追加があって、ますます楽しくなっています。
全容はGithub上のリリースノートを見ていただくとして、今日は改良された数値精度を試してみます。
これまでは
jq
は、IEEE 754の倍精度形式(binary64)で数値を表現します。この仕様では、仮数部(A × 10BのAの部分)は10進数でだいたい16桁くらいまで、指数部(Bの部分)は308くらいまで正確に表現できます。それ以上では、丸め誤差が発生します。
たとえば、次で用いている円周率のπは小数点以下が20桁で定義されていますが(Cのmath.h
から取ってきました)、バージョン1.6では切り捨てられてしまいます。
$ jq-1.6 --version
jq-1.6 # バージョン1.6を使っています
$ echo 3.14159265358979323846 | jq-1.6 '.'
3.141592653589793 # 切り捨て
蛇足ですが、数値の桁数を調べるには、あらかじめ(jq
に入力する前に)文字列化して、length
です。
$ echo '"3.14159265358979323846"' | jq-1.6 'length'
22 # 先頭の値とドットを含めて22桁なので、小数点以下は20桁
-n
オプション(ロングフォーマットは--null-input
)を使ってフィルタ内に記述するのは✕です。その時点でIEEE 754表現に変換されてしまうからです。
$ jq-1.6 -n '3.14159265358979323846 | tostring | length'
17 # お前はすでに切り捨てられている
JavaScriptでは
JavaScriptでも事情は同じです。数値はIEEE 754倍精度で表現されるので、一定以上の精度の値は丸められます。
Node.jsで試してみます。
$ node
Welcome to Node.js v20.9.0.
Type ".help" for more information.
> JSON.parse(3.14159265358979323846)
3.141592653589793
これからは
数値の桁数は、読み込まれた時点ではその精度が保たれてるようになりました。
$ jq --version
jq-1.7.1 # 1.7です
$ echo 3.14159265358979323846 | jq '.'
3.14159265358979323846 # 精度が保存されます
なので、-n
でフィルタ内に記述することもできます。
$ jq -n '3.14159265358979323846 | tostring | length'
22 # 今度はあってる
<
や>
などの比較演算もできます。小数点数以下20桁のπとその末尾を1つ増やした値を比較してみます。
# V V が1つ違う
$ jq -n '[3.14159265358979323846, 3.14159265358979323847] | .[0] < .[1]'
true
1.6ではこうはいきません。
$ jq-1.6 -n '[3.14159265358979323846, 3.14159265358979323847] | .[0] < .[1]'
false
比較演算はできますが、普通の演算では1.6同様に桁落ちします。演算と同時にIEEE 754表現に変換されるからです。0を加えてみます。
$ jq -n '3.14159265358979323846 + 0'
3.141592653589793
おわりに
数字(文字)をずらずら書き連ねるだけで数値を表現できるJSONでは、数値の精度に制約はありません。しかし、その処理系ではIEEE 754など表現形式の精度に依存します。そのため、JSON仕様のRFC 8259は極端に大きい、あるいは精度の高い数値を使うときは、相互運用性に気をつけるように注意を促しています。
比較ができるようになったからといって、大きな数値を使うのは考えものなのは、これまでと変わりません。
1.7では、他にも、細かいところで性能向上も図られています。まだ1.6をお使いなら、これを機会に1.7にアップグレードしましょう。
参考
-
./jq ...
jq
のオフィシャルサイトです(英文)。 -
Github jqland/jq Releases ...
jq
のリリースノートです(英文)。 - 『jqハンドブック』(2021)... 1.6の数値精度の問題は、この本の5.8節で紹介しています。ご購入はこちらから【出版社 | honto | amazon.co.jp | ヨドバシカメラ】。
- 「jqのむだづかい」 ...
jq
ではまずやろうとは思わない処理の探求記録です。完成版は他の(通常機能な)レシピとともに『jqクックブック』(2023)に掲載しました。ご購入はこちらから【出版社 | honto | amazon.co.jp | ヨドバシカメラ】。