try_from_degrees rounds away from the nearest sixteenth at two f32 inputs
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 84/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- rust
- Área
- embedded-iot
Línea de trabajo
Empieza en src/lib.rs:441 y lee las pruebas existentes ties_round_half_away_from_zero y the_rejection_boundaries_are_exact_and_closed. Comprueba los dos valores f32 reportados y el oráculo f64 documentado; después añade cobertura para los límites internos de medio LSB y confirma que try_from_degrees devuelve los valores redondeados documentados sin cambiar el comportamiento de rechazo.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Rust
- Estrellas
- 2
- Forks
- 7
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de OpenDevicePartnership/tmp108
-
audit:SBOS663A bug documentation impact:field-visible verdict:contradicts
Dificultad 1/5 Menos de una hora Aptitud para principiantes 95/100
-
audit:SBOS663A bug enhancement impact:documentation
Dificultad 3/5 1-2 días Aptitud para principiantes 74/100
-
audit:SBOS663A impact:latent question verdict:unsupported
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
-
bug
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
Todos los issues de OpenDevicePartnership/tmp108
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
rubys/roundhouse#1917 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 2 días
-
good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
Los mantenedores suelen responder en 1 día
-
[cosmic-applet-battery] Division by zero displays NaN% when UPower reports max_brightness = 0Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
pop-os/cosmic-applets#1619 ·
Los mantenedores suelen responder en 3 días
-
binding:python bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día