Spark `round()` on floating-point types diverges from Spark HALF_UP semantics

オープン 初心者向け
#22,812 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
76/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
静か
技術スタック
rust, spark, sql

調査の方向性

datafusion/spark/src/function/math/round.rs から始め、特にエントリーポイント round_float と、BigDecimal および HALF_UP の動作を説明している既存のドキュメントコメントを確認してください。SQL の例 1.255 と 1.005 を再現し、その後、浮動小数点入力に対して Spark 互換の結果になることを示す回帰テストのカバレッジを追加してください。FloatType と DoubleType の両方を含めます。

索引モデルが issue の本文から書いたものです。

説明

Describe the bug

The Spark-compatible round() function gives different results from Apache Spark when the input is a floating-point type (FloatType/DoubleType) and the value's binary representation is slightly off from its decimal literal.

Spark's RoundBase rounds a double as BigDecimal(d).setScale(scale, HALF_UP), where BigDecimal(Double) is java.math.BigDecimal.valueOf(d) — i.e. it parses the shortest round-trip decimal string of the double (Double.toString). DataFusion's round_float instead does naive binary-float arithmetic, (value * 10^scale).round() / 10^scale, which rounds the already-imprecise binary value and diverges at the half-way point.

To Reproduce
SELECT round(1.255::double, 2::int);
-- Spark:      1.26
-- DataFusion: 1.25

SELECT round(1.005::double, 2::int);
-- Spark:      1.01
-- DataFusion: 1.0

The cause is that 1.255 and 1.005 are stored as binary doubles a hair below the decimal value (1.2549999999999999..., 1.00499999999999989...). Spark sees the shortest decimal string ("1.255", "1.005") and applies HALF_UP, so the tie rounds away from zero. DataFusion multiplies the raw binary value by 100, which stays below the half-way point, and rounds down.

Expected behavior

Match Spark: round via the shortest round-trip decimal representation with HALF_UP (ties away from zero), for both DoubleType and FloatType (Spark widens float to double first via f.toDouble).

Additional context

The existing doc comment on round_float already describes the intended BigDecimal / HALF_UP behaviour; the implementation simply doesn't match it. I have a fix and will open a PR referencing this issue.

datafusion/spark/src/function/math/round.rs

主要言語
Rust
スター
9.3k
フォーク
2.4k
平均マージ
3日 8時間
マージ済み PR(30日)
354

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

apache/datafusion のほかの issue

apache/datafusion の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。