Shared Rust kernels
ported/bit_common
All modules · quoted at commit 9e1884369a67 of DnaCalc/DnaCalc. Comments are the source's own.
coerce_bit_operand · 8 lines · calc-func/src/ported/bit_common.rs on GitHubpub fn coerce_bit_operand(n: f64) -> Result<u64, WorksheetErrorCode> {
// Excel's bit operands must already be integers. Truncation is only
// permitted for a shift count, not for the number being shifted/masked.
if !n.is_finite() || n < 0.0 || n > BIT_MAX as f64 || n != n.trunc() {
return Err(WorksheetErrorCode::Num);
}
Ok(n as u64)
}
Used by 5 functions.
coerce_shift_count · 7 lines · calc-func/src/ported/bit_common.rs on GitHubpub fn coerce_shift_count(n: f64) -> Result<i32, WorksheetErrorCode> {
let truncated = n.trunc();
if !n.is_finite() || truncated.abs() > BIT_SHIFT_MAX as f64 {
return Err(WorksheetErrorCode::Num);
}
Ok(truncated as i32)
}
Used by 2 functions.
bit_shift_kernel · 30 lines · calc-func/src/ported/bit_common.rs on GitHub/// Common BITLSHIFT/BITRSHIFT graph observed in Excel 16.0 build 20430, CV2.
/// A zero operand bypasses the finite shift-count range check; an admitted
/// truncated count with magnitude 49..=53 publishes zero in either direction.
/// These are empirical exceptions to the published <=53/48-bit description.
/// Evidence: w111-broad-20260929 BITLSHIFT/BITRSHIFT Value2 witness sets.
pub fn bit_shift_kernel(number: f64, shift: f64, left: bool) -> Result<f64, WorksheetErrorCode> {
let number = coerce_bit_operand(number)?;
if !shift.is_finite() {
return Err(WorksheetErrorCode::Num);
}
if number == 0 {
return Ok(0.0);
}
let shift = coerce_shift_count(shift)?;
if shift.abs() > 48 {
return Ok(0.0);
}
let shift = if left { shift } else { -shift };
let result = if shift >= 0 {
// checked_shl only checks whether the count is >=64: it does not
// detect discarded high bits. Check the Excel 48-bit bound first.
if number > BIT_MAX >> shift {
return Err(WorksheetErrorCode::Num);
}
number << shift
} else {
number >> -shift
};
Ok(result as f64)
}
Used by 2 functions.