Struct rug::float::SmallFloat
[−]
[src]
#[repr(C)]pub struct SmallFloat { /* fields omitted */ }
A small float that does not require any memory allocation.
This can be useful when you have a primitive number type but need
a reference to a Float
. The SmallFloat
will have a precision according to the type of the primitive used
to set its value.
i8
,u8
: theSmallFloat
will have eight bits of precision.i16
,u16
: theSmallFloat
will have 16 bits of precision.i32
,u32
: theSmallFloat
will have 32 bits of precision.i64
,u64
: theSmallFloat
will have 64 bits of precision.f32
: theSmallFloat
will have 24 bits of precision.f64
: theSmallFloat
will have 53 bits of precision.
The SmallFloat
type can be coerced to a
Float
, as it implements Deref
with a
Float
target.
Examples
use rug::Float; use rug::float::SmallFloat; // `a` requires a heap allocation, has 53-bit precision let mut a = Float::with_val(53, 250); // `b` can reside on the stack let b = SmallFloat::from(-100f64); a += &*b; assert_eq!(a, 150); // another computation: a *= &*b; assert_eq!(a, -15000);
Methods
impl SmallFloat
[src]
fn new() -> SmallFloat
Creates a SmallFloat
with value 0.
Methods from Deref<Target = Float>
fn prec(&self) -> u32
Returns the precision.
fn to_integer(&self) -> Option<Integer>
Converts to an integer, rounding to the nearest.
fn to_integer_round(&self, round: Round) -> Option<(Integer, Ordering)>
Converts to an integer, applying the specified rounding method.
fn to_integer_exp(&self) -> Option<(Integer, i32)>
If the value is a finite number, returns
an Integer
and exponent such that
self
is exactly equal to the integer multiplied by two
raised to the power of the exponent.
Examples
use rug::{Assign, Float}; use rug::float::Special; let mut float = Float::with_val(16, 6.5); // 6.5 in binary is 110.1 // Since the precision is 16 bits, this becomes // 1101_0000_0000_0000 times two to the power of -12 let (int, exp) = float.to_integer_exp().unwrap(); assert_eq!(int, 0b1101_0000_0000_0000); assert_eq!(exp, -13); float.assign(0); let (zero, _) = float.to_integer_exp().unwrap(); assert_eq!(zero, 0); float.assign(Special::Infinity); assert!(float.to_integer_exp().is_none());
fn to_rational(&self) -> Option<Rational>
If the value is a finite number, returns
a Rational
number preserving all the
precision of the value.
Examples
use rug::{Float, Rational}; use rug::float::Round; use std::str::FromStr; use std::cmp::Ordering; // Consider the number 123,456,789 / 10,000,000,000. let res = Float::from_str_round("0.0123456789", 35, Round::Down); let (f, f_rounding) = res.unwrap(); assert_eq!(f_rounding, Ordering::Less); let r = Rational::from_str("123456789/10000000000").unwrap(); // Set fr to the value of f exactly. let fr = f.to_rational().unwrap(); // Since f == fr and f was rounded down, r != fr. assert_ne!(r, fr); let (frf, frf_rounding) = Float::with_val_round(35, &fr, Round::Down); assert_eq!(frf_rounding, Ordering::Equal); assert_eq!(frf, f); assert_eq!(format!("{:.9}", frf), "1.23456789e-2");
In the following example, the Float
values can be
represented exactly.
use rug::Float; let large_f = Float::with_val(16, 6.5); let large_r = large_f.to_rational().unwrap(); let small_f = Float::with_val(16, -0.125); let small_r = small_f.to_rational().unwrap(); assert_eq!(*large_r.numer(), 13); assert_eq!(*large_r.denom(), 2); assert_eq!(*small_r.numer(), -1); assert_eq!(*small_r.denom(), 8);
fn to_i32_saturating(&self) -> Option<i32>
Converts to an i32
, rounding to the nearest.
If the value is too small or too large for the target type,
the minimum or maximum value allowed is returned.
If the value is a NaN, None
is returned.
fn to_i32_saturating_round(&self, round: Round) -> Option<i32>
Converts to an i32
, applying the specified rounding method.
If the value is too small or too large for the target type,
the minimum or maximum value allowed is returned.
If the value is a NaN, None
is returned.
fn to_u32_saturating(&self) -> Option<u32>
Converts to a u32
, rounding to the nearest.
If the value is too small or too large for the target type,
the minimum or maximum value allowed is returned.
If the value is a NaN, None
is returned.
fn to_u32_saturating_round(&self, round: Round) -> Option<u32>
Converts to a u32
, applying the specified rounding method.
If the value is too small or too large for the target type,
the minimum or maximum value allowed is returned.
If the value is a NaN, None
is returned.
fn to_f32(&self) -> f32
Converts to an f32
, rounding to the nearest.
If the value is too small or too large for the target type, the minimum or maximum value allowed is returned.
fn to_f32_round(&self, round: Round) -> f32
Converts to an f32
, applying the specified rounding method.
If the value is too small or too large for the target type, the minimum or maximum value allowed is returned.
fn to_f64(&self) -> f64
Converts to an f64
, rounding to the nearest.
If the value is too small or too large for the target type, the minimum or maximum value allowed is returned.
fn to_f64_round(&self, round: Round) -> f64
Converts to an f64
, applying the specified rounding method.
If the value is too small or too large for the target type, the minimum or maximum value allowed is returned.
fn to_f32_exp(&self) -> (f32, i32)
Converts to an f32
and an exponent, rounding to the nearest.
The returned f32
is in the range 0.5 ≤ x < 1.
If the value is too small or too large for the target type, the minimum or maximum value allowed is returned.
Examples
use rug::Float; let zero = Float::new(64); let (d0, exp0) = zero.to_f32_exp(); assert_eq!((d0, exp0), (0.0, 0)); let three_eighths = Float::with_val(64, 0.375); let (d3_8, exp3_8) = three_eighths.to_f32_exp(); assert_eq!((d3_8, exp3_8), (0.75, -1));
fn to_f32_exp_round(&self, round: Round) -> (f32, i32)
Converts to an f32
and an exponent, applying the specified
rounding method.
The returned f32
is in the range 0.5 ≤ x < 1.
If the value is too small or too large for the target type, the minimum or maximum value allowed is returned.
Examples
use rug::Float; use rug::float::Round; let frac_10_3 = Float::with_val(64, 10) / 3u32; let (f_down, exp_down) = frac_10_3.to_f32_exp_round(Round::Down); assert_eq!((f_down, exp_down), (0.8333333, 2)); let (f_up, exp_up) = frac_10_3.to_f32_exp_round(Round::Up); assert_eq!((f_up, exp_up), (0.8333334, 2));
fn to_f64_exp(&self) -> (f64, i32)
Converts to an f64
and an exponent, rounding to the nearest.
The returned f64
is in the range 0.5 ≤ x < 1.
If the value is too small or too large for the target type, the minimum or maximum value allowed is returned.
fn to_f64_exp_round(&self, round: Round) -> (f64, i32)
Converts to an f64
and an exponent, applying the specified
rounding method.
The returned f64
is in the range 0.5 ≤ x < 1.
If the value is too small or too large for the target type, the minimum or maximum value allowed is returned.
fn to_string_radix(&self, radix: i32, num_digits: Option<usize>) -> String
Returns a string representation of self
for the specified
radix
rounding to the nearest.
The exponent is encoded in decimal. The output string will have enough precision such that reading it again will give the exact same number.
Examples
use rug::Float; use rug::float::Special; let neg_inf = Float::with_val(53, Special::MinusInfinity); assert_eq!(neg_inf.to_string_radix(10, None), "-inf"); assert_eq!(neg_inf.to_string_radix(16, None), "-@inf@"); let twentythree = Float::with_val(8, 23); assert_eq!(twentythree.to_string_radix(10, None), "2.300e1"); assert_eq!(twentythree.to_string_radix(16, None), "1.70@1"); assert_eq!(twentythree.to_string_radix(10, Some(2)), "2.3e1"); assert_eq!(twentythree.to_string_radix(16, Some(4)), "1.700@1");
Panics
Panics if radix
is less than 2 or greater than 36.
fn to_string_radix_round(
&self,
radix: i32,
num_digits: Option<usize>,
round: Round
) -> String
&self,
radix: i32,
num_digits: Option<usize>,
round: Round
) -> String
Returns a string representation of self
for the specified
radix
applying the specified rounding method.
The exponent is encoded in decimal. The output string will have enough precision such that reading it again will give the exact same number.
Panics
Panics if radix
is less than 2 or greater than 36.
fn is_integer(&self) -> bool
Returns true
if self
is an integer.
fn is_nan(&self) -> bool
Returns true
if self
is not a number.
fn is_infinite(&self) -> bool
Returns true
if self
is plus or minus infinity.
fn is_finite(&self) -> bool
Returns true
if self
is a finite number,
that is neither NaN nor infinity.
fn is_zero(&self) -> bool
Returns true
if self
is plus or minus zero.
fn is_normal(&self) -> bool
Returns true
if self
is a normal number, that is neither
NaN, nor infinity, nor zero. Note that Float
cannot be
subnormal.
fn sign(&self) -> Option<Ordering>
Returns Ordering::Less
if self
is less than zero,
Ordering::Greater
if self
is greater than zero, or
Ordering::Equal
if self
is equal to zero.
fn cmp_abs(&self, other: &Float) -> Option<Ordering>
Compares the absolute values of self
and other
.
fn get_exp(&self) -> Option<i32>
Returns the exponent of self
if self
is a normal number,
otherwise None
. The significand is assumed to be in the
range [0.5,1).
fn get_sign(&self) -> bool
Returns the sign bit, that is true
if the number is negative.
fn square(self) -> Float
Computes the square, rounding to the nearest.
fn square_ref(&self) -> SquareRef
Compuets the square.
fn sqrt(self) -> Float
Computes the square root, rounding to the nearest.
fn sqrt_ref(&self) -> SqrtRef
Computes the square root.
fn recip_sqrt(self) -> Float
Computes the reciprocal square root, rounding to the nearest.
fn recip_sqrt_ref(&self) -> RecipSqrtRef
Computes the reciprocal square root.
fn cbrt(self) -> Float
Computes the cube root, rounding to the nearest.
fn cbrt_ref(&self) -> CbrtRef
Computes the cube root.
fn root(self, k: u32) -> Float
Computes the kth root, rounding to the nearest.
fn root_ref(&self, k: u32) -> RootRef
Computes the kth root.
fn abs(self) -> Float
Computes the absolute value.
fn abs_ref(&self) -> AbsRef
Computes the absolute value.
fn recip(self) -> Float
Computes the reciprocal, rounding to the nearest.
fn recip_ref(&self) -> RecipRef
Computes the reciprocal.
fn abs_diff(self, other: &Float) -> Float
Computes the positive difference between self
and
other
, rounding to the nearest.
fn abs_diff_ref<'a>(&'a self, other: &'a Float) -> AbsDiffRef<'a>
Computes the positive difference.
fn ln(self) -> Float
Computes the natural logarithm, rounding to the nearest.
fn ln_ref(&self) -> LnRef
Computes the natural logarithm.
fn log2(self) -> Float
Computes the logarithm to base 2, rounding to the nearest.
fn log2_ref(&self) -> Log2Ref
Computes the logarithm to base 2.
fn log10(self) -> Float
Computes the logarithm to base 10, rounding to the nearest.
fn log10_ref(&self) -> Log10Ref
Computes the logarithm to base 10.
fn exp(self) -> Float
Computes the exponential, rounding to the nearest.
fn exp_ref(&self) -> ExpRef
Computes the exponential.
fn exp2(self) -> Float
Computes 2 to the power of self
, rounding to the nearest.
fn exp2_ref(&self) -> Exp2Ref
Computes 2 to the power of the value.
fn exp10(self) -> Float
Computes 10 to the power of self
, rounding to the nearest.
fn exp10_ref(&self) -> Exp10Ref
Computes 10 to the power of the value.
fn sin(self) -> Float
Computes the sine, rounding to the nearest.
fn sin_ref(&self) -> SinRef
Computes the sine.
fn cos(self) -> Float
Computes the cosine, rounding to the nearest.
fn cos_ref(&self) -> CosRef
Computes the cosine.
fn tan(self) -> Float
Computes the tangent, rounding to the nearest.
fn tan_ref(&self) -> TanRef
Computes the tangent.
fn sin_cos(self, cos: Float) -> (Float, Float)
Computes the sine and cosine of self
, rounding to the
nearest.
The sine is stored in self
and keeps its precision,
while the cosine is stored in cos
keeping its precision.
fn sin_cos_ref(&self) -> SinCosRef
Computes the sine and cosine.
Examples
use rug::{Assign, Float}; // sin(0.5) = 0.47943, cos(0.5) = 0.87758 let angle = Float::with_val(53, 0.5); let r = angle.sin_cos_ref(); // use only 10 bits of precision here to // make comparison easier let (mut sin, mut cos) = (Float::new(10), Float::new(10)); (&mut sin, &mut cos).assign(r); assert_eq!(sin, Float::with_val(10, 0.47943)); assert_eq!(cos, Float::with_val(10, 0.87748));
fn sec(self) -> Float
Computes the secant, rounding to the nearest.
fn sec_ref(&self) -> SecRef
Computes the secant.
fn csc(self) -> Float
Computes the cosecant, rounding to the nearest.
fn csc_ref(&self) -> CscRef
Computes the cosecant.
fn cot(self) -> Float
Computes the cotangent, rounding to the nearest.
fn cot_ref(&self) -> CotRef
Computes the cotangent.
fn acos(self) -> Float
Computes the arc-cosine, rounding to the nearest.
fn acos_ref(&self) -> AcosRef
Computes the arc-cosine.
fn asin(self) -> Float
Computes the arc-sine, rounding to the nearest.
fn asin_ref(&self) -> AsinRef
Computes the arc-sine.
fn atan(self) -> Float
Computes the arc-tangent, rounding to the nearest.
fn atan_ref(&self) -> AtanRef
Computes the arc-tangent.
fn atan2(self, other: &Float) -> Float
Computes the arc-tangent2 of self
and other
, rounding to
the nearest.
This is similar to the arc-tangent of self / other
, except
in the cases when either self
or other
or both are zero or
infinity.
fn atan2_ref<'a>(&'a self, other: &'a Float) -> Atan2Ref<'a>
Computes the arc-tangent.
fn sinh(self) -> Float
Computes the hyperbolic sine, rounding to the nearest.
fn sinh_ref(&self) -> SinhRef
Computes the hyperbolic sine.
fn cosh(self) -> Float
Computes the hyperbolic cosine, rounding to the nearest.
fn cosh_ref(&self) -> CoshRef
Computes the hyperbolic cosine.
fn tanh(self) -> Float
Computes the hyperbolic tangent, rounding to the nearest.
fn tanh_ref(&self) -> TanhRef
Computes the hyperbolic tangent.
fn sinh_cosh(self, cos: Float) -> (Float, Float)
Computes the hyperbolic sine and cosine of self
,
rounding to the nearest.
The sine is stored in self
and keeps its precision,
while the cosine is stored in cos
keeping its precision.
fn sinh_cosh_ref(&self) -> SinhCoshRef
Computes the hyperbolic sine and cosine.
Examples
use rug::{Assign, Float}; // sinh(0.5) = 0.52110, cosh(0.5) = 1.1276 let angle = Float::with_val(53, 0.5); let r = angle.sinh_cosh_ref(); // use only 10 bits of precision here to // make comparison easier let (mut sinh, mut cosh) = (Float::new(10), Float::new(10)); (&mut sinh, &mut cosh).assign(r); assert_eq!(sinh, Float::with_val(10, 0.52110)); assert_eq!(cosh, Float::with_val(10, 1.1276));
fn sech(self) -> Float
Computes the hyperbolic secant, rounding to the nearest.
fn sech_ref(&self) -> SechRef
Computes the hyperbolic secant.
fn csch(self) -> Float
Computes the hyperbolic cosecant, rounding to the nearest.
fn csch_ref(&self) -> CschRef
Computes the hyperbolic cosecant.
fn coth(self) -> Float
Computes the hyperbolic cotangent, rounding to the nearest.
fn coth_ref(&self) -> CothRef
Computes the hyperbolic cotangent.
fn acosh(self) -> Float
Computes the inverse hyperbolic cosine, rounding to the nearest.
fn acosh_ref(&self) -> AcoshRef
Computes the inverse hyperbolic cosine
fn asinh(self) -> Float
Computes the inverse hyperbolic sine, rounding to the nearest.
fn asinh_ref(&self) -> AsinhRef
Computes the inverse hyperbolic sine.
fn atanh(self) -> Float
Computes the inverse hyperbolic tangent, rounding to the nearest.
fn atanh_ref(&self) -> AtanhRef
Computes the inverse hyperbolic tangent.
fn ln_1p(self) -> Float
Computes the natural logarithm of one plus self
, rounding to
the nearest.
fn ln_1p_ref(&self) -> Ln1pRef
Computes the natural logorithm of one plus the value.
fn exp_m1(self) -> Float
Subtracts one from the exponential of self
, rounding to the
nearest.
fn exp_m1_ref(&self) -> ExpM1Ref
Computes one less than the exponential of the value.
fn eint(self) -> Float
Computes the exponential integral, rounding to the nearest.
fn eint_ref(&self) -> EintRef
Computes the exponential integral.
fn li2(self) -> Float
Computes the real part of the dilogarithm of self
, rounding
to the nearest.
fn li2_ref(&self) -> Li2Ref
Computes the real part of the dilogarithm of the value.
fn gamma(self) -> Float
Computes the value of the Gamma function on self
, rounding
to the nearest.
fn gamma_ref(&self) -> GammaRef
Computes the Gamma function on the value.
fn ln_gamma(self) -> Float
Computes the logarithm of the Gamma function on self
,
rounding to the nearest.
fn ln_gamma_ref(&self) -> LnGammaRef
Computes the logarithm of the Gamma function on the value.
fn ln_abs_gamma(self) -> (Float, Ordering)
Computes the logarithm of the absolute value of the Gamma
function on self
, rounding to the nearest.
Returns Ordering::Less
if the Gamma function is negative, or
Ordering::Greater
if the Gamma function is positive.
Examples
use rug::Float; use rug::float::Constant; use std::cmp::Ordering; // gamma of 1/2 is sqrt(pi) let ln_gamma_64 = Float::with_val(64, Constant::Pi).sqrt().ln(); let f = Float::with_val(53, 0.5); let (ln_gamma, sign) = f.ln_abs_gamma(); // gamma of 1/2 is positive assert_eq!(sign, Ordering::Greater); // check to 53 significant bits assert_eq!(ln_gamma, Float::with_val(53, &ln_gamma_64));
If the Gamma function is negative, the sign returned is
Ordering::Less
.
use rug::Float; use rug::float::Constant; use std::cmp::Ordering; // gamma of -1/2 is -2 * sqrt(pi) let abs_gamma_64 = Float::with_val(64, Constant::Pi).sqrt() * 2u32; let ln_gamma_64 = abs_gamma_64.ln(); let f = Float::with_val(53, -0.5); let (ln_gamma, sign) = f.ln_abs_gamma(); // gamma of -1/2 is negative assert_eq!(sign, Ordering::Less); // check to 53 significant bits assert_eq!(ln_gamma, Float::with_val(53, &ln_gamma_64));
fn ln_abs_gamma_ref(&self) -> LnAbsGammaRef
Computes the logarithm of the absolute value of the Gamma
function on val
.
Examples
use rug::{Assign, Float}; use rug::float::Constant; use std::cmp::Ordering; let neg1_2 = Float::with_val(53, -0.5); // gamma of -1/2 is -2 * sqrt(pi) let abs_gamma_64 = Float::with_val(64, Constant::Pi).sqrt() * 2u32; let ln_gamma_64 = abs_gamma_64.ln(); // Assign rounds to the nearest let r = neg1_2.ln_abs_gamma_ref(); let (mut f, mut sign) = (Float::new(53), Ordering::Equal); (&mut f, &mut sign).assign(r); // gamma of -1/2 is negative assert_eq!(sign, Ordering::Less); // check to 53 significant bits assert_eq!(f, Float::with_val(53, &ln_gamma_64));
fn digamma(self) -> Float
Computes the value of the Digamma function on self
, rounding
to the nearest.
fn digamma_ref(&self) -> DigammaRef
Computes the Digamma function on the value.
fn zeta(self) -> Float
Computes the value of the Riemann Zeta function on self
,
rounding to the nearest.
fn zeta_ref(&self) -> ZetaRef
Computes the Riemann Zeta function on the value.
fn erf(self) -> Float
Computes the value of the error function, rounding to the nearest.
fn erf_ref(&self) -> ErfRef
Computes the error function.
fn erfc(self) -> Float
Computes the value of the complementary error function, rounding to the nearest.
fn erfc_ref(&self) -> ErfcRef
Computes the complementary error function.
fn j0(self) -> Float
Computes the value of the first kind Bessel function of order 0, rounding to the nearest.
fn j0_ref(&self) -> J0Ref
Computes the first kind Bessel function of order 0.
fn j1(self) -> Float
Computes the value of the first kind Bessel function of order 1, rounding to the nearest.
fn j1_ref(&self) -> J1Ref
Computes the first kind Bessel function of order 1.
fn jn(self, n: i32) -> Float
Computes the value of the first kind Bessel function of order n, rounding to the nearest.
fn jn_ref(&self, n: i32) -> JnRef
Computes the first kind Bessel function of order n.
fn y0(self) -> Float
Computes the value of the second kind Bessel function of order 0, rounding to the nearest.
fn y0_ref(&self) -> Y0Ref
Computes the second kind Bessel function of order 0.
fn y1(self) -> Float
Computes the value of the second kind Bessel function of order 1, rounding to the nearest.
fn y1_ref(&self) -> Y1Ref
Computes the second kind Bessel function of order 1.
fn yn(self, n: i32) -> Float
Computes the value of the second kind Bessel function of order n, rounding to the nearest.
fn yn_ref(&self, n: i32) -> YnRef
Computes the second kind Bessel function of order n.
fn agm(self, other: &Float) -> Float
Computes the arithmetic-geometric mean of self
and other
,
rounding to the nearest.
fn agm_ref<'a>(&'a self, other: &'a Float) -> AgmRef<'a>
Computes the arithmetic-geometric mean.
fn hypot(self, other: &Float) -> Float
Computes the Euclidean norm of self
and other
, rounding to
the nearest.
fn hypot_ref<'a>(&'a self, other: &'a Float) -> HypotRef<'a>
Computes the Euclidean norm.
fn ai(self) -> Float
Computes the value of the Airy function Ai on self
, rounding
to the nearest.
fn ai_ref(&self) -> AiRef
Computes the Airy function Ai on the value.
fn ceil(self) -> Float
Rounds up to the next higher integer.
fn ceil_ref(&self) -> CeilRef
Rounds up to the next higher integer. The result may be rounded again when assigned to the target.
fn floor(self) -> Float
Rounds down to the next lower integer.
fn floor_ref(&self) -> FloorRef
Rounds down to the next lower integer. The result may be rounded again when assigned to the target.
fn round(self) -> Float
Rounds to the nearest integer, rounding half-way cases away from zero.
fn round_ref(&self) -> RoundRef
Rounds to the nearest integer, rounding half-way cases away from zero. The result may be rounded again when assigned to the target.
Examples
use rug::{AssignRound, Float}; use rug::float::Round; let f = Float::with_val(53, 6.5); // 6.5 (binary 110.1) is rounded to 7 (binary 111) let r = f.round_ref(); // use only 2 bits of precision in destination let mut dst = Float::new(2); // 7 (binary 111) is rounded to 8 (binary 1000) by // round-even rule in order to store in 2-bit Float, even // though 6 (binary 110) is closer to original 6.5). dst.assign_round(r, Round::Nearest); assert_eq!(dst, 8);
fn trunc(self) -> Float
Rounds to the next integer towards zero.
fn trunc_ref(&self) -> TruncRef
Rounds to the next integer towards zero. The result may be rounded again when assigned to the target.
fn fract(self) -> Float
Gets the fractional part of the number.
fn fract_ref(&self) -> FractRef
Gets the fractional part of the number.
fn trunc_fract(self, fract: Float) -> (Float, Float)
Gets the integer and fractional parts of the number, rounding to the nearest.
The integer part is stored in self
and keeps its
precision, while the fractional part is stored in fract
keeping its precision.
fn trunc_fract_ref(&self) -> TruncFractRef
Gets the integer and fractional parts of the number.
Trait Implementations
impl Default for SmallFloat
[src]
fn default() -> SmallFloat
Returns the "default value" for a type. Read more
impl Deref for SmallFloat
[src]
type Target = Float
The resulting type after dereferencing
fn deref(&self) -> &Float
The method called to dereference a value
impl<T> From<T> for SmallFloat where
SmallFloat: Assign<T>,
[src]
SmallFloat: Assign<T>,
fn from(val: T) -> SmallFloat
Performs the conversion.