try_from_degrees rounds away from the nearest sixteenth at two f32 inputs
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 84/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- rust
- 領域
- embedded-iot
調査の方向性
src/lib.rs:441から始め、既存のties_round_half_away_from_zeroテストとthe_rejection_boundaries_are_exact_and_closedテストを読みます。報告された2つのf32値と、文書化されたf64オラクルを確認し、内部の半LSB境界のカバレッジを追加して、try_from_degreesが文書化された丸め値を返し、拒否の動作を変更しないことを確認します。
索引モデルが issue の本文から書いたものです。
説明
Celsius::try_from_degrees documents its rounding as:
Values are rounded to the nearest
sixteenth of a degree, half away from zero.
src/lib.rs:404-405
It does not do that for two inputs. Both are the f32 immediately below
±1/32 — strictly nearer to zero than to one sixteenth, so both must round
to 0. Both round to ±1.
Measured
Exhaustive, not sampled: the function was transcribed verbatim into a
scratch binary and run under rustc -O against an f64 oracle over
all 2^32 f32 bit patterns.
exhaustive sweep of all 2^32 f32 inputs
TOTAL DISAGREEMENTS: 2
bits=0x3cffffff x= 3.12499981373548508e-2 driver=Ok(1) documented=Ok(0)
bits=0xbcffffff x=-3.12499981373548508e-2 driver=Ok(-1) documented=Ok(0)
The oracle applies the documented contract in f64: scale by 16 (exact),
round half away from zero, then reject if the rounded value leaves
-2048..=2047. Two disagreements, and no others anywhere in the domain.
Cause
src/lib.rs:441:
let rounded = if scaled >= 0.0 { scaled + 0.5 } else { scaled - 0.5 };
degrees * 16.0 is exact — multiplying by a power of two. The error is in
the half-add. For x = 0.031249998137354851, scaled is 0.49999997,
and 0.49999997f32 + 0.5f32 is 0.99999997 exactly, which is not
representable in binary32; it rounds to 1.0 (ties-to-even against
0.99999994). Truncation then yields 1 instead of 0.
So the tie test happens after a rounding step that can manufacture a tie
that the input did not have.
Scope
Narrow but real. try_from_degrees is the public boundary feeding
set_low_limit / set_high_limit, so an affected input programs a
threshold one LSB (0.0625 °C) away from its advertised value. The two
inputs are not values anyone types as a decimal literal; they arise from
computed floats.
This is a defect against the driver's own documented contract, not
against the datasheet — SBOS663A §7.5.2 specifies the 0.0625 °C
resolution and two's-complement format, and says nothing about how an
arbitrary float should reach a representable value. Rounding policy is
driver policy, as it is for snap_hysteresis in #76.
Why the existing tests miss it
ops_tests covers exact ties (ties_round_half_away_from_zero,
src/lib.rs:4079) and the outer rejection boundaries
(the_rejection_boundaries_are_exact_and_closed, src/lib.rs:4106).
Neither covers the representable neighbours just inside a tie, which is
precisely where the half-add misbehaves.
Options
- Round without an intermediate half-add. Compare against the tie
directly, or perform the add in a wider type. Deletes the failure mode
rather than special-casing it. - Widen to
f64for the rounding step only. One cast;no_stdsafe;
the oracle above is exactly this and is correct over the whole domain. - Document the exception. Cheapest, but the contract sentence would
have to name two specific bit patterns, which is worse than fixing it.
Any of 1 or 2 changes observable output for two inputs, so it wants a
changelog-visible commit.
Suggested test
Enumerate every internal half-LSB boundary and its two f32 neighbours
(12,285 cases) against an independent oracle, rather than a hand-picked
list. The full 2^32 sweep runs in ~2 s on 16 threads if you ever want it
as a one-off.
Provenance
Raised by the datasheet compliance audit of PR #77, then reproduced
independently. Not a regression — the behaviour predates #77; it was
simply never asserted.
- 主要言語
- Rust
- スター
- 2
- フォーク
- 7
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
OpenDevicePartnership/tmp108 のほかの issue
-
audit:SBOS663A bug documentation impact:field-visible verdict:contradicts
難易度 1/5 1時間未満 初心者へのやさしさ 95/100
-
audit:SBOS663A bug enhancement impact:documentation
難易度 3/5 1〜2日 初心者へのやさしさ 74/100
-
audit:SBOS663A impact:latent question verdict:unsupported
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
-
bug
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
OpenDevicePartnership/tmp108 の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
rubys/roundhouse#1917 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 2 日以内に返信
-
good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
pop-os/cosmic-applets#1619 ·
メンテナーはふだん 3 日以内に返信
-
binding:python bug
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信