diff --git a/Cargo.toml b/Cargo.toml
index e7274f6..a01b1be 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,8 +14,5 @@ num = { version = "0.1.40", default-features=false, features=["bigint"] }
num-traits = "0.1.40"
serde = { version = "1", optional = true }
-[dev-dependencies.rand]
-version = "0.3"
-
[dev-dependencies.serde_json]
version = "1"
diff --git a/examples/floating-precision.rs b/examples/floating-precision.rs
new file mode 100644
index 0000000..2813a1e
--- /dev/null
+++ b/examples/floating-precision.rs
@@ -0,0 +1,14 @@
+extern crate bigdecimal;
+
+use bigdecimal::BigDecimal;
+use std::str::FromStr;
+
+fn main() {
+ let input = std::env::args().skip(1).next().unwrap_or("0.7".to_string());
+ let decimal = BigDecimal::from_str(&input).expect("invalid decimal");
+ let floating = f32::from_str(&input).expect("invalid float");
+
+ println!("Input string: {}", &input);
+ println!("Big-decimal value: {:.10}", decimal);
+ println!("Floating-point value: {:.10}", floating);
+}
diff --git a/src/lib.rs b/src/lib.rs
index aa869b5..210e655 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,14 +12,14 @@
//! A Big Decimal
//!
-//! BigDecimal allows storing any real number to arbitrary precision; which
+//! `BigDecimal` allows storing any real number to arbitrary precision; which
//! avoids common floating point errors (such as 0.1 + 0.2 ≠ 0.3) at the
//! cost of complexity.
//!
//! Internally, `BigDecimal` uses a `BigInt` object, paired with a 64-bit
//! integer which determines the position of the decimal point. Therefore,
-//! the precision *is not* actually arbitrary, but limitied to 2^63 decimal
-//! places.
+//! the precision *is not* actually arbitrary, but limited to 263
+//! decimal places.
//!
//! Common numerical operations are overloaded, so we can treat them
//! the same way we treat other numbers.
@@ -27,6 +27,18 @@
//! It is not recommended to convert a floating point number to a decimal
//! directly, as the floating point representation may be unexpected.
//!
+//! # Example
+//!
+//! ```
+//! use bigdecimal::BigDecimal;
+//! use std::str::FromStr;
+//!
+//! let input = "0.8";
+//! let dec = BigDecimal::from_str(&input).unwrap();
+//! let float = f32::from_str(&input).unwrap();
+//!
+//! println!("Input ({}) with 10 decimals: {} vs {})", input, dec, float);
+//! ```
extern crate num;
extern crate num_traits as traits;
@@ -181,17 +193,14 @@ impl BigDecimal {
if new_scale > self.scale {
let scale_diff = new_scale - self.scale;
let int_val = &self.int_val * ten_to_the(scale_diff as u64);
- return BigDecimal::new(int_val, new_scale);
-
+ BigDecimal::new(int_val, new_scale)
} else if new_scale < self.scale {
let scale_diff = self.scale - new_scale;
let int_val = &self.int_val / ten_to_the(scale_diff as u64);
- return BigDecimal::new(int_val, new_scale);
-
+ BigDecimal::new(int_val, new_scale)
} else {
- return self.clone();
+ self.clone()
}
-
}
/// Return the sign of the `BigDecimal` as `num::bigint::Sign`.
@@ -380,23 +389,15 @@ impl Ord for BigDecimal {
impl PartialEq for BigDecimal {
#[inline]
fn eq(&self, rhs: &BigDecimal) -> bool {
- // println!("{}E{} =?= {}E{}",
- // self.int_val,
- // self.scale,
- // rhs.int_val,
- // rhs.scale);
-
// fix scale and test equality
if self.scale > rhs.scale {
let scaled_int_val = &rhs.int_val * ten_to_the((self.scale - rhs.scale) as u64);
- return self.int_val == scaled_int_val;
-
+ self.int_val == scaled_int_val
} else if self.scale < rhs.scale {
let scaled_int_val = &self.int_val * ten_to_the((rhs.scale - self.scale) as u64);
- return scaled_int_val == rhs.int_val;
-
+ scaled_int_val == rhs.int_val
} else {
- return self.int_val == rhs.int_val;
+ self.int_val == rhs.int_val
}
}
}
@@ -542,9 +543,9 @@ impl<'a, 'b> Div<&'b BigDecimal> for &'a BigDecimal {
#[allow(non_snake_case)]
fn div(self, other: &BigDecimal) -> BigDecimal {
let scale = self.scale - other.scale;
- let ref num = self.int_val;
- let ref den = other.int_val;
- let (quotient, remainder) = num.div_rem(&den);
+ let num = &self.int_val;
+ let den = &other.int_val;
+ let (quotient, remainder) = num.div_rem(den);
// no remainder - quotient is final solution
if remainder == BigInt::zero() {
@@ -558,7 +559,7 @@ impl<'a, 'b> Div<&'b BigDecimal> for &'a BigDecimal {
let MAX_ITERATIONS = 100;
let mut iteration_count = 0;
while remainder != BigInt::zero() && iteration_count < MAX_ITERATIONS {
- let (q, r) = remainder.div_rem(&den);
+ let (q, r) = remainder.div_rem(den);
quotient = quotient * BIG_TEN + q;
remainder = r * BIG_TEN;
@@ -683,7 +684,7 @@ impl fmt::Display for BigDecimal {
};
// Concatenate everything
- let complete = if after.len() > 0 {
+ let complete = if !after.is_empty() {
before + "." + after.as_str()
} else {
before
@@ -760,7 +761,7 @@ impl Num for BigDecimal {
let mut digits = String::from(lead);
// copy all trailing characters after '.' into the digits string
- digits.extend(trail.chars());
+ digits.push_str(trail);
(digits, trail.len() as i64)
}
@@ -769,7 +770,7 @@ impl Num for BigDecimal {
let scale = decimal_offset - exponent_value;
let big_int = try!(BigInt::from_str_radix(&digits, radix));
- return Ok(BigDecimal::new(big_int, scale));
+ Ok(BigDecimal::new(big_int, scale))
}
}
@@ -783,7 +784,7 @@ impl ToPrimitive for BigDecimal {
fn to_u64(&self) -> Option {
match self.sign() {
Sign::Plus => self.with_scale(0).int_val.to_u64(),
- Sign::NoSign => return Some(0),
+ Sign::NoSign => Some(0),
Sign::Minus => None,
}
}