use std::error::Error;
/// Returns the Nth digit after the decimal point.
///
/// # Arguments
///
/// * `value` - The floating-point number to inspect.
/// * `position` - The digit position after the decimal point (1-based).
///
/// # Returns
///
/// * `Ok(digit)` - The requested digit (0-9).
/// * `Err(...)` - If position is less than 1.
///
/// # Examples
///
/// ```
/// get_nth_decimal_digit(123.456789, 1) -> 4
/// get_nth_decimal_digit(123.456789, 2) -> 5
/// get_nth_decimal_digit(123.456789, 3) -> 6
/// ```
fn get_nth_decimal_digit(value: f64, position: usize) -> Result<u8, String> {
if position == 0 {
return Err("position must be greater than zero".to_string());
}
// Work with positive numbers only.
let value = value.abs();
// Convert to a string with fixed precision.
let number_str = format!("{:.15}", value);
// Locate the decimal point.
let decimal_pos = match number_str.find('.') {
Some(pos) => pos,
None => return Ok(0),
};
// Calculate the index of the requested digit.
let digit_index = decimal_pos + position;
// Return 0 if the digit does not exist.
if digit_index >= number_str.len() {
return Ok(0);
}
let digit_char = number_str
.chars()
.nth(digit_index)
.unwrap_or('0');
Ok(digit_char.to_digit(10).unwrap_or(0) as u8)
}
fn main() -> Result<(), Box<dyn Error>> {
let number: f64 = 123.456789;
println!("Number: {}\n", number);
for position in 1..=6 {
let digit = get_nth_decimal_digit(number, position)?;
println!("{position} digit after decimal = {digit}");
}
println!("\nAdditional Examples");
println!("-------------------");
println!(
"123.456789, position 4 -> {}",
get_nth_decimal_digit(123.456789, 4)?
);
println!(
"-98.7654, position 2 -> {}",
get_nth_decimal_digit(-98.7654, 2)?
);
println!(
"1.2, position 5 -> {}",
get_nth_decimal_digit(1.2, 5)?
);
Ok(())
}
/*
run:
Number: 123.456789
1 digit after decimal = 4
2 digit after decimal = 5
3 digit after decimal = 6
4 digit after decimal = 7
5 digit after decimal = 8
6 digit after decimal = 9
Additional Examples
-------------------
123.456789, position 4 -> 7
-98.7654, position 2 -> 6
1.2, position 5 -> 0
*/