use intrinsics;
use mem;
-use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
-use num::{Float, FromStrRadix};
-use num::strconv;
-use str::FromStr;
+use num::{Float, FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
+use num::from_str_radix;
use option::Option;
pub const RADIX: uint = 2u;
#[allow(missing_docs)]
#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
pub fn from_str_hex(src: &str) -> Option<f32> {
- strconv::from_str_radix_float(src, 16)
-}
-
-impl FromStr for f32 {
- /// Convert a string in base 10 to a float.
- /// Accepts an optional decimal exponent.
- ///
- /// This function accepts strings such as
- ///
- /// * '3.14'
- /// * '+3.14', equivalent to '3.14'
- /// * '-3.14'
- /// * '2.5E10', or equivalently, '2.5e10'
- /// * '2.5E-10'
- /// * '.' (understood as 0)
- /// * '5.'
- /// * '.5', or, equivalently, '0.5'
- /// * '+inf', 'inf', '-inf', 'NaN'
- ///
- /// Leading and trailing whitespace represent an error.
- ///
- /// # Arguments
- ///
- /// * src - A string
- ///
- /// # Return value
- ///
- /// `None` if the string did not represent a valid number. Otherwise,
- /// `Some(n)` where `n` is the floating-point number represented by `src`.
- #[inline]
- fn from_str(src: &str) -> Option<f32> {
- strconv::from_str_radix_float(src, 10u)
- }
-}
-
-impl FromStrRadix for f32 {
- /// Convert a string in a given base to a float.
- ///
- /// Due to possible conflicts, this function does **not** accept
- /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
- /// does it recognize exponents of any kind.
- ///
- /// Leading and trailing whitespace represent an error.
- ///
- /// # Arguments
- ///
- /// * src - A string
- /// * radix - The base to use. Must lie in the range [2 .. 36]
- ///
- /// # Return value
- ///
- /// `None` if the string did not represent a valid number. Otherwise,
- /// `Some(n)` where `n` is the floating-point number represented by `src`.
- #[inline]
- fn from_str_radix(src: &str, radix: uint) -> Option<f32> {
- strconv::from_str_radix_float(src, radix)
- }
+ from_str_radix(src, 16)
}
use intrinsics;
use mem;
-use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
-use num::{Float, FromStrRadix};
-use num::strconv;
-use str::FromStr;
+use num::{Float, FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
+use num::from_str_radix;
use option::Option;
// FIXME(#5527): These constants should be deprecated once associated
#[allow(missing_docs)]
#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
pub fn from_str_hex(src: &str) -> Option<f64> {
- strconv::from_str_radix_float(src, 16)
-}
-
-impl FromStr for f64 {
- /// Convert a string in base 10 to a float.
- /// Accepts an optional decimal exponent.
- ///
- /// This function accepts strings such as:
- ///
- /// * '3.14'
- /// * '-3.14'
- /// * '2.5E10', or equivalently, '2.5e10'
- /// * '2.5E-10'
- /// * '.' (understood as 0)
- /// * '5.'
- /// * '.5', or, equivalently, '0.5'
- /// * inf', '-inf', 'NaN'
- ///
- /// Leading and trailing whitespace represent an error.
- ///
- /// # Arguments
- ///
- /// * src - A string
- ///
- /// # Return value
- ///
- /// `none` if the string did not represent a valid number. Otherwise,
- /// `Some(n)` where `n` is the floating-point number represented by `src`.
- #[inline]
- fn from_str(src: &str) -> Option<f64> {
- strconv::from_str_radix_float(src, 10u)
- }
-}
-
-impl FromStrRadix for f64 {
- /// Convert a string in a given base to a float.
- ///
- /// Leading and trailing whitespace represent an error.
- ///
- /// # Arguments
- ///
- /// * src - A string
- /// * radix - The base to use. Must lie in the range [2 .. 36]
- ///
- /// # Return value
- ///
- /// `None` if the string did not represent a valid number. Otherwise,
- /// `Some(n)` where `n` is the floating-point number represented by `src`.
- #[inline]
- fn from_str_radix(src: &str, radix: uint) -> Option<f64> {
- strconv::from_str_radix_float(src, radix)
- }
+ from_str_radix(src, 16)
}
#[unstable]
pub const MAX: $T = !MIN;
-#[experimental = "might need to return Result"]
-impl ::str::FromStr for $T {
- #[inline]
- fn from_str(s: &str) -> ::option::Option<$T> {
- ::num::strconv::from_str_radix_int(s, 10)
- }
-}
-
-#[experimental = "might need to return Result"]
-impl ::num::FromStrRadix for $T {
- #[inline]
- fn from_str_radix(s: &str, radix: uint) -> ::option::Option<$T> {
- ::num::strconv::from_str_radix_int(s, radix)
- }
-}
-
))
#![allow(missing_docs)]
-use intrinsics;
use {int, i8, i16, i32, i64};
use {uint, u8, u16, u32, u64};
use {f32, f64};
+use char::Char;
use clone::Clone;
use cmp::{PartialEq, Eq};
use cmp::{PartialOrd, Ord};
+use intrinsics;
+use iter::Iterator;
use kinds::Copy;
use mem::size_of;
use ops::{Add, Sub, Mul, Div, Rem, Neg};
use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
use option::{Option, Some, None};
-
-pub mod strconv;
+use str::{FromStr, from_str, StrPrelude};
/// Simultaneous division and remainder
#[inline]
FromStrRadix::from_str_radix(str, radix)
}
+macro_rules! from_str_radix_float_impl {
+ ($T:ty) => {
+ #[experimental = "might need to return Result"]
+ impl FromStr for $T {
+ /// Convert a string in base 10 to a float.
+ /// Accepts an optional decimal exponent.
+ ///
+ /// This function accepts strings such as
+ ///
+ /// * '3.14'
+ /// * '+3.14', equivalent to '3.14'
+ /// * '-3.14'
+ /// * '2.5E10', or equivalently, '2.5e10'
+ /// * '2.5E-10'
+ /// * '.' (understood as 0)
+ /// * '5.'
+ /// * '.5', or, equivalently, '0.5'
+ /// * '+inf', 'inf', '-inf', 'NaN'
+ ///
+ /// Leading and trailing whitespace represent an error.
+ ///
+ /// # Arguments
+ ///
+ /// * src - A string
+ ///
+ /// # Return value
+ ///
+ /// `None` if the string did not represent a valid number. Otherwise,
+ /// `Some(n)` where `n` is the floating-point number represented by `src`.
+ #[inline]
+ fn from_str(src: &str) -> Option<$T> {
+ from_str_radix(src, 10)
+ }
+ }
+
+ #[experimental = "might need to return Result"]
+ impl FromStrRadix for $T {
+ /// Convert a string in a given base to a float.
+ ///
+ /// Due to possible conflicts, this function does **not** accept
+ /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
+ /// does it recognize exponents of any kind.
+ ///
+ /// Leading and trailing whitespace represent an error.
+ ///
+ /// # Arguments
+ ///
+ /// * src - A string
+ /// * radix - The base to use. Must lie in the range [2 .. 36]
+ ///
+ /// # Return value
+ ///
+ /// `None` if the string did not represent a valid number. Otherwise,
+ /// `Some(n)` where `n` is the floating-point number represented by `src`.
+ fn from_str_radix(src: &str, radix: uint) -> Option<$T> {
+ assert!(radix >= 2 && radix <= 36,
+ "from_str_radix_float: must lie in the range `[2, 36]` - found {}",
+ radix);
+
+ // Special values
+ match src {
+ "inf" => return Some(Float::infinity()),
+ "-inf" => return Some(Float::neg_infinity()),
+ "NaN" => return Some(Float::nan()),
+ _ => {},
+ }
+
+ let (is_positive, src) = match src.slice_shift_char() {
+ (None, _) => return None,
+ (Some('-'), "") => return None,
+ (Some('-'), src) => (false, src),
+ (Some(_), _) => (true, src),
+ };
+
+ // The significand to accumulate
+ let mut sig = if is_positive { 0.0 } else { -0.0 };
+ // Necessary to detect overflow
+ let mut prev_sig = sig;
+ let mut cs = src.chars().enumerate();
+ // Exponent prefix and exponent index offset
+ let mut exp_info = None::<(char, uint)>;
+
+ // Parse the integer part of the significand
+ for (i, c) in cs {
+ match c.to_digit(radix) {
+ Some(digit) => {
+ // shift significand one digit left
+ sig = sig * (radix as $T);
+
+ // add/subtract current digit depending on sign
+ if is_positive {
+ sig = sig + ((digit as int) as $T);
+ } else {
+ sig = sig - ((digit as int) as $T);
+ }
+
+ // Detect overflow by comparing to last value, except
+ // if we've not seen any non-zero digits.
+ if prev_sig != 0.0 {
+ if is_positive && sig <= prev_sig
+ { return Some(Float::infinity()); }
+ if !is_positive && sig >= prev_sig
+ { return Some(Float::neg_infinity()); }
+
+ // Detect overflow by reversing the shift-and-add process
+ if is_positive && (prev_sig != (sig - digit as $T) / radix as $T)
+ { return Some(Float::infinity()); }
+ if !is_positive && (prev_sig != (sig + digit as $T) / radix as $T)
+ { return Some(Float::neg_infinity()); }
+ }
+ prev_sig = sig;
+ },
+ None => match c {
+ 'e' | 'E' | 'p' | 'P' => {
+ exp_info = Some((c, i + 1));
+ break; // start of exponent
+ },
+ '.' => {
+ break; // start of fractional part
+ },
+ _ => {
+ return None;
+ },
+ },
+ }
+ }
+
+ // If we are not yet at the exponent parse the fractional
+ // part of the significand
+ if exp_info.is_none() {
+ let mut power = 1.0;
+ for (i, c) in cs {
+ match c.to_digit(radix) {
+ Some(digit) => {
+ // Decrease power one order of magnitude
+ power = power / (radix as $T);
+ // add/subtract current digit depending on sign
+ sig = if is_positive {
+ sig + (digit as $T) * power
+ } else {
+ sig - (digit as $T) * power
+ };
+ // Detect overflow by comparing to last value
+ if is_positive && sig < prev_sig
+ { return Some(Float::infinity()); }
+ if !is_positive && sig > prev_sig
+ { return Some(Float::neg_infinity()); }
+ prev_sig = sig;
+ },
+ None => match c {
+ 'e' | 'E' | 'p' | 'P' => {
+ exp_info = Some((c, i + 1));
+ break; // start of exponent
+ },
+ _ => {
+ return None; // invalid number
+ },
+ },
+ }
+ }
+ }
+
+ // Parse and calculate the exponent
+ let exp = match exp_info {
+ Some((c, offset)) => {
+ let base = match c {
+ 'E' | 'e' if radix == 10 => 10u as $T,
+ 'P' | 'p' if radix == 16 => 2u as $T,
+ _ => return None,
+ };
+
+ // Parse the exponent as decimal integer
+ let src = src[offset..];
+ let (is_positive, exp) = match src.slice_shift_char() {
+ (Some('-'), src) => (false, from_str::<uint>(src)),
+ (Some('+'), src) => (true, from_str::<uint>(src)),
+ (Some(_), _) => (true, from_str::<uint>(src)),
+ (None, _) => return None,
+ };
+
+ match (is_positive, exp) {
+ (true, Some(exp)) => base.powi(exp as i32),
+ (false, Some(exp)) => 1.0 / base.powi(exp as i32),
+ (_, None) => return None,
+ }
+ },
+ None => 1.0, // no exponent
+ };
+
+ Some(sig * exp)
+ }
+ }
+ }
+}
+from_str_radix_float_impl!(f32)
+from_str_radix_float_impl!(f64)
+
+macro_rules! from_str_radix_int_impl {
+ ($T:ty) => {
+ #[experimental = "might need to return Result"]
+ impl FromStr for $T {
+ #[inline]
+ fn from_str(src: &str) -> Option<$T> {
+ from_str_radix(src, 10)
+ }
+ }
+
+ #[experimental = "might need to return Result"]
+ impl FromStrRadix for $T {
+ fn from_str_radix(src: &str, radix: uint) -> Option<$T> {
+ assert!(radix >= 2 && radix <= 36,
+ "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
+ radix);
+
+ let is_signed_ty = (0 as $T) > Int::min_value();
+
+ match src.slice_shift_char() {
+ (Some('-'), src) if is_signed_ty => {
+ // The number is negative
+ let mut result = 0;
+ for c in src.chars() {
+ let x = match c.to_digit(radix) {
+ Some(x) => x,
+ None => return None,
+ };
+ result = match result.checked_mul(radix as $T) {
+ Some(result) => result,
+ None => return None,
+ };
+ result = match result.checked_sub(x as $T) {
+ Some(result) => result,
+ None => return None,
+ };
+ }
+ Some(result)
+ },
+ (Some(_), _) => {
+ // The number is signed
+ let mut result = 0;
+ for c in src.chars() {
+ let x = match c.to_digit(radix) {
+ Some(x) => x,
+ None => return None,
+ };
+ result = match result.checked_mul(radix as $T) {
+ Some(result) => result,
+ None => return None,
+ };
+ result = match result.checked_add(x as $T) {
+ Some(result) => result,
+ None => return None,
+ };
+ }
+ Some(result)
+ },
+ (None, _) => None,
+ }
+ }
+ }
+ }
+}
+from_str_radix_int_impl!(int)
+from_str_radix_int_impl!(i8)
+from_str_radix_int_impl!(i16)
+from_str_radix_int_impl!(i32)
+from_str_radix_int_impl!(i64)
+from_str_radix_int_impl!(uint)
+from_str_radix_int_impl!(u8)
+from_str_radix_int_impl!(u16)
+from_str_radix_int_impl!(u32)
+from_str_radix_int_impl!(u64)
+
// DEPRECATED
macro_rules! trait_impl {
+++ /dev/null
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
-
-#![allow(missing_docs)]
-
-use char::Char;
-use iter::Iterator;
-use num;
-use num::{Int, Float};
-use option::{None, Option, Some};
-use str::{from_str, StrPrelude};
-
-pub fn from_str_radix_float<T: Float>(src: &str, radix: uint) -> Option<T> {
- assert!(radix >= 2 && radix <= 36,
- "from_str_radix_float: must lie in the range `[2, 36]` - found {}",
- radix);
-
- let _0: T = Float::zero();
- let _1: T = Float::one();
- let radix_t: T = num::cast(radix as int).unwrap();
-
- // Special values
- match src {
- "inf" => return Some(Float::infinity()),
- "-inf" => return Some(Float::neg_infinity()),
- "NaN" => return Some(Float::nan()),
- _ => {},
- }
-
- let (is_positive, src) = match src.slice_shift_char() {
- (None, _) => return None,
- (Some('-'), "") => return None,
- (Some('-'), src) => (false, src),
- (Some(_), _) => (true, src),
- };
-
- // The significand to accumulate
- let mut sig = if is_positive { _0 } else { -_0 };
- // Necessary to detect overflow
- let mut prev_sig = sig;
- let mut cs = src.chars().enumerate();
- // Exponent prefix and exponent index offset
- let mut exp_info = None::<(char, uint)>;
-
- // Parse the integer part of the significand
- for (i, c) in cs {
- match c.to_digit(radix) {
- Some(digit) => {
- // shift significand one digit left
- sig = sig * radix_t;
-
- // add/subtract current digit depending on sign
- if is_positive {
- sig = sig + num::cast(digit as int).unwrap();
- } else {
- sig = sig - num::cast(digit as int).unwrap();
- }
-
- // Detect overflow by comparing to last value, except
- // if we've not seen any non-zero digits.
- if prev_sig != _0 {
- if is_positive && sig <= prev_sig
- { return Some(Float::infinity()); }
- if !is_positive && sig >= prev_sig
- { return Some(Float::neg_infinity()); }
-
- // Detect overflow by reversing the shift-and-add process
- let digit: T = num::cast(digit as int).unwrap();
- if is_positive && (prev_sig != ((sig - digit) / radix_t))
- { return Some(Float::infinity()); }
- if !is_positive && (prev_sig != ((sig + digit) / radix_t))
- { return Some(Float::neg_infinity()); }
- }
- prev_sig = sig;
- },
- None => match c {
- 'e' | 'E' | 'p' | 'P' => {
- exp_info = Some((c, i + 1));
- break; // start of exponent
- },
- '.' => {
- break; // start of fractional part
- },
- _ => {
- return None;
- },
- },
- }
- }
-
- // If we are not yet at the exponent parse the fractional
- // part of the significand
- if exp_info.is_none() {
- let mut power = _1;
- for (i, c) in cs {
- match c.to_digit(radix) {
- Some(digit) => {
- let digit: T = num::cast(digit).unwrap();
- // Decrease power one order of magnitude
- power = power / radix_t;
- // add/subtract current digit depending on sign
- sig = if is_positive {
- sig + digit * power
- } else {
- sig - digit * power
- };
- // Detect overflow by comparing to last value
- if is_positive && sig < prev_sig
- { return Some(Float::infinity()); }
- if !is_positive && sig > prev_sig
- { return Some(Float::neg_infinity()); }
- prev_sig = sig;
- },
- None => match c {
- 'e' | 'E' | 'p' | 'P' => {
- exp_info = Some((c, i + 1));
- break; // start of exponent
- },
- _ => {
- return None; // invalid number
- },
- },
- }
- }
- }
-
- // Parse and calculate the exponent
- let exp = match exp_info {
- Some((c, offset)) => {
- let base: T = match c {
- 'E' | 'e' if radix == 10 => num::cast(10u).unwrap(),
- 'P' | 'p' if radix == 16 => num::cast(2u).unwrap(),
- _ => return None,
- };
-
- // Parse the exponent as decimal integer
- let src = src[offset..];
- let (is_positive, exp) = match src.slice_shift_char() {
- (Some('-'), src) => (false, from_str::<uint>(src)),
- (Some('+'), src) => (true, from_str::<uint>(src)),
- (Some(_), _) => (true, from_str::<uint>(src)),
- (None, _) => return None,
- };
-
- match (is_positive, exp) {
- (true, Some(exp)) => base.powi(exp as i32),
- (false, Some(exp)) => _1 / base.powi(exp as i32),
- (_, None) => return None,
- }
- },
- None => _1, // no exponent
- };
-
- Some(sig * exp)
-}
-
-pub fn from_str_radix_int<T: Int>(src: &str, radix: uint) -> Option<T> {
- assert!(radix >= 2 && radix <= 36,
- "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
- radix);
-
- fn cast<T: Int>(x: uint) -> T {
- num::cast(x).unwrap()
- }
-
- let _0: T = Int::zero();
- let _1: T = Int::one();
- let is_signed = _0 > Int::min_value();
-
- let (is_positive, src) = match src.slice_shift_char() {
- (Some('-'), src) if is_signed => (false, src),
- (Some(_), _) => (true, src),
- (None, _) => return None,
- };
-
- let mut xs = src.chars().map(|c| {
- c.to_digit(radix).map(cast)
- });
- let radix = cast(radix);
- let mut result = _0;
-
- if is_positive {
- for x in xs {
- let x = match x {
- Some(x) => x,
- None => return None,
- };
- result = match result.checked_mul(radix) {
- Some(result) => result,
- None => return None,
- };
- result = match result.checked_add(x) {
- Some(result) => result,
- None => return None,
- };
- }
- } else {
- for x in xs {
- let x = match x {
- Some(x) => x,
- None => return None,
- };
- result = match result.checked_mul(radix) {
- Some(result) => result,
- None => return None,
- };
- result = match result.checked_sub(x) {
- Some(result) => result,
- None => return None,
- };
- }
- }
-
- Some(result)
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use option::*;
- use num::Float;
-
- #[test]
- fn from_str_issue7588() {
- let u : Option<u8> = from_str_radix_int("1000", 10);
- assert_eq!(u, None);
- let s : Option<i16> = from_str_radix_int("80000", 10);
- assert_eq!(s, None);
- let f : Option<f32> = from_str_radix_float("10000000000000000000000000000000000000000", 10);
- assert_eq!(f, Some(Float::infinity()))
- let fe : Option<f32> = from_str_radix_float("1e40", 10);
- assert_eq!(fe, Some(Float::infinity()))
- }
-
- #[test]
- fn test_from_str_radix_float() {
- let x1 : Option<f64> = from_str_radix_float("-123.456", 10);
- assert_eq!(x1, Some(-123.456));
- let x2 : Option<f32> = from_str_radix_float("123.456", 10);
- assert_eq!(x2, Some(123.456));
- let x3 : Option<f32> = from_str_radix_float("-0.0", 10);
- assert_eq!(x3, Some(-0.0));
- let x4 : Option<f32> = from_str_radix_float("0.0", 10);
- assert_eq!(x4, Some(0.0));
- let x4 : Option<f32> = from_str_radix_float("1.0", 10);
- assert_eq!(x4, Some(1.0));
- let x5 : Option<f32> = from_str_radix_float("-1.0", 10);
- assert_eq!(x5, Some(-1.0));
- }
-}
#[unstable]
pub const MAX: $T = 0 as $T - 1 as $T;
-#[experimental = "might need to return Result"]
-impl ::str::FromStr for $T {
- #[inline]
- fn from_str(s: &str) -> ::option::Option<$T> {
- ::num::strconv::from_str_radix_int(s, 10)
- }
-}
-
-#[experimental = "might need to return Result"]
-impl ::num::FromStrRadix for $T {
- #[inline]
- fn from_str_radix(s: &str, radix: uint) -> ::option::Option<$T> {
- ::num::strconv::from_str_radix_int(s, radix)
- }
-}
-
))