try_from_degrees rounds away from the nearest sixteenth at two f32 inputs
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 84/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- rust
- Lĩnh vực
- embedded-iot
Hướng nghiên cứu
Bắt đầu tại src/lib.rs:441 và đọc các test hiện có ties_round_half_away_from_zero và the_rejection_boundaries_are_exact_and_closed. Kiểm tra hai giá trị f32 đã được báo cáo và oracle f64 được ghi nhận, sau đó bổ sung coverage cho các ranh giới nửa LSB nội bộ và xác nhận rằng try_from_degrees trả về các giá trị đã làm tròn được ghi nhận mà không thay đổi hành vi từ chối.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- Rust
- Star
- 2
- Fork
- 7
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của OpenDevicePartnership/tmp108
-
audit:SBOS663A bug documentation impact:field-visible verdict:contradicts
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 95/100
-
audit:SBOS663A bug enhancement impact:documentation
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 74/100
-
audit:SBOS663A impact:latent question verdict:unsupported
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
-
bug
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
Tất cả issue của OpenDevicePartnership/tmp108
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
rubys/roundhouse#1917 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 2 ngày
-
good first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[cosmic-applet-battery] Division by zero displays NaN% when UPower reports max_brightness = 0Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
pop-os/cosmic-applets#1619 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
binding:python bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày