Shared Rust kernels
ported/engineering_radix_family
All modules · quoted at commit 9e1884369a67 of DnaCalc/DnaCalc. Comments are the source's own.
upper_ascii_digit_value · 7 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubfn upper_ascii_digit_value(ch: char) -> Option<u32> {
match ch {
'0'..='9' => Some((ch as u8 - b'0') as u32),
'A'..='Z' => Some((ch as u8 - b'A') as u32 + 10),
_ => None,
}
}
Used by 9 functions.
normalize_radix_text · 3 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubfn normalize_radix_text(text: &str) -> String {
text.to_ascii_uppercase()
}
Used by 9 functions.
parse_radix_text · 32 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubfn parse_radix_text(text: &str, source: RadixSpec) -> Result<i64, WorksheetErrorCode> {
let normalized = normalize_radix_text(text);
if normalized.is_empty() {
return Ok(0);
}
if normalized.len() > source.max_chars {
return Err(WorksheetErrorCode::Num);
}
let mut raw: u64 = 0;
for ch in normalized.chars() {
let Some(digit) = upper_ascii_digit_value(ch) else {
return Err(WorksheetErrorCode::Num);
};
if digit >= source.radix {
return Err(WorksheetErrorCode::Num);
}
raw = raw
.checked_mul(source.radix as u64)
.and_then(|value| value.checked_add(digit as u64))
.ok_or(WorksheetErrorCode::Num)?;
}
if normalized.len() == source.max_chars {
let sign_mask = 1_u64 << (source.bits - 1);
if raw & sign_mask != 0 {
return Ok(raw as i64 - (1_i64 << source.bits));
}
}
Ok(raw as i64)
}
Used by 9 functions.
normalize_places · 13 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubpub(crate) fn normalize_places(places: Option<f64>) -> Result<Option<usize>, WorksheetErrorCode> {
match places {
None => Ok(None),
Some(raw) => {
let truncated = raw.trunc();
if !raw.is_finite() || !(1.0..=10.0).contains(&truncated) {
Err(WorksheetErrorCode::Num)
} else {
Ok(Some(truncated as usize))
}
}
}
}
Used by 9 functions.
min_signed_value · 3 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubfn min_signed_value(spec: RadixSpec) -> i64 {
-(1_i64 << (spec.bits - 1))
}
Used by 9 functions.
max_signed_value · 3 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubfn max_signed_value(spec: RadixSpec) -> i64 {
(1_i64 << (spec.bits - 1)) - 1
}
Used by 9 functions.
encode_signed_value · 35 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubfn encode_signed_value(
value: i64,
target: RadixSpec,
places: Option<f64>,
) -> Result<ExcelText, WorksheetErrorCode> {
if value < min_signed_value(target) || value > max_signed_value(target) {
return Err(WorksheetErrorCode::Num);
}
// Excel validates an explicitly supplied width even when a negative value
// always publishes its full ten-character two's-complement encoding.
let places = normalize_places(places)?;
if value < 0 {
let raw = ((1_i128 << target.bits) + i128::from(value)) as f64;
return base_kernel(raw, target.radix as f64, Some(target.max_chars as f64));
}
let digits = base_kernel(value as f64, target.radix as f64, None)?;
let digits_string = digits.to_string_lossy();
match places {
Some(min_length) => {
if digits_string.len() > min_length {
Err(WorksheetErrorCode::Num)
} else {
let padded = format!("{digits_string:0>width$}", width = min_length);
Ok(ExcelText::from_utf16_code_units(
padded.encode_utf16().collect(),
))
}
}
None => Ok(digits),
}
}
Used by 9 functions.
trunc_i64 · 3 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubfn trunc_i64(number: f64) -> i64 {
number.trunc() as i64
}
Used by 3 functions.
dec_to_target_kernel · 7 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubpub(crate) fn dec_to_target_kernel(
number: f64,
places: Option<f64>,
target: RadixSpec,
) -> Result<ExcelText, WorksheetErrorCode> {
encode_signed_value(trunc_i64(number), target, places)
}
Used by 3 functions.
source_to_decimal_kernel · 6 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubpub(crate) fn source_to_decimal_kernel(
source_text: &str,
source: RadixSpec,
) -> Result<f64, WorksheetErrorCode> {
parse_radix_text(source_text, source).map(|value| value as f64)
}
Used by 3 functions.
source_to_target_kernel · 9 lines · calc-func/src/ported/engineering_radix_family.rs on GitHubpub(crate) fn source_to_target_kernel(
source_text: &str,
places: Option<f64>,
source: RadixSpec,
target: RadixSpec,
) -> Result<ExcelText, WorksheetErrorCode> {
let decimal = parse_radix_text(source_text, source)?;
encode_signed_value(decimal, target, places)
}
Used by 6 functions.