2017-12-27 67 views
0

"42.1"과 같은 8 진수 문자열을 가져 와서 부동 소수점을 가져와야합니다 (34.125). Rust에서 이것을하는 가장 좋은 방법은 무엇입니까? 나는 there previously was a from_str_radix function, but it's now removed을 본다.녹에서 float로 8 진수 문자열을 구문 분석하는 방법은 무엇입니까?

+0

어디에서 오는 8 진수의 부동 소수점 숫자입니까? 어쩌면 소스를 수정하는 것이 더 쉬울까요? BTW, 8 진수 "42.1"은 34.125입니다. – red75prime

+0

실제로 구현이 실제로 중단되었습니다. "당신이 제공 한 링크에서 보듯이"누군가가 이것을 필요로하는 끔찍한 유스 케이스를 갖고 있다면 자신의 글을 쓸 수 있습니다. 하나의 특정한 기수에 관심이 있다면 쉽게 할 수 있습니다. 특히 지수가 10과 16 이외의 기지에서는 합법적이지 않기 때문에 더욱 그렇습니다. 게다가 현재의 구현보다 정확하지 않을 수는 없습니다. " – Kroltan

+0

이것은 크레이트를위한 훌륭한 기회입니다! – Kroltan

답변

1
use std::fmt; 

#[derive(Debug, Clone, PartialEq, Eq)] 
pub struct ParseFloatError { 
    _private:(), 
} 

impl ParseFloatError { 
    fn new() -> ParseFloatError { 
     ParseFloatError { _private:() } 
    } 
} 

impl fmt::Display for ParseFloatError { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "Could not parse float") 
    } 
} 

pub fn parse_float_radix(s: &str, radix: u32) -> Result<f64, ParseFloatError> { 
    let s2 = s.replace(".", ""); 
    let i = i64::from_str_radix(&s2, radix).map_err(|_| ParseFloatError::new())?; 
    let count = s.split('.').count(); 
    let fraction_len: usize; 
    match count { 
     0 => unreachable!(), 
     1 => fraction_len = 0, 
     2 => fraction_len = s.split('.').last().unwrap().len(), 
     _ => return Err(ParseFloatError::new()), 
    } 
    let f = (i as f64)/f64::from(radix).powi(fraction_len as i32); 
    Ok(f) 
} 

fn main() { 
    println!("{}", parse_float_radix("42.1", 8).unwrap()); 
} 

먼저 입력을 정수로 구문 분석 한 다음 radix^number_of_fractional_digits로 나눕니다.

과학 표기법이나 무한대 또는 NaN과 같은 특수 값을 지원하지 않습니다. 또한 중간 정수가 오버플로되면 실패합니다.

+0

나는 이것을 상자에 넣으려고하고 있지만, 당신이 작성한 것에 대해 어떤 라이센스를 쓸지 모르겠다. – vpzomtrrfrt

+0

@vpzomtrrfrt 나는 [CC0] (https://creativecommons.org/)에 위의 코드를 사용권으로한다. public domain/zero/1.0 /). 비록이 코드가 범용 크레이트에 필요한 품질을 가지고 있다고는 생각하지 않습니다. 특히 정수 넘침 문제는 문제가됩니다. – CodesInChaos

+0

https://crates.io/crates/parse_float_radix가 이제 시작되었지만 여러 목적으로 유용하지는 않을 것이라는 데 동의합니다. – vpzomtrrfrt