pub trait FixedPointNumber: Sized + Copy + Default + Debug + Saturating + Bounded + Eq + PartialEq + Ord + PartialOrd + CheckedSub + CheckedAdd + CheckedMul + CheckedDiv + Add + Sub + Div + Mul + Zero + One {
    type Inner: Debug + One + CheckedMul + CheckedDiv + FixedPointOperand;

    const DIV: Self::Inner;
    const SIGNED: bool;
Show 22 methods fn from_inner(int: Self::Inner) -> Self; fn into_inner(self) -> Self::Inner; fn accuracy() -> Self::Inner { ... } fn saturating_from_integer<N: FixedPointOperand>(int: N) -> Self { ... } fn checked_from_integer<N: Into<Self::Inner>>(int: N) -> Option<Self> { ... } fn saturating_from_rational<N: FixedPointOperand, D: FixedPointOperand>(
        n: N,
        d: D
    ) -> Self { ... } fn checked_from_rational<N: FixedPointOperand, D: FixedPointOperand>(
        n: N,
        d: D
    ) -> Option<Self> { ... } fn checked_mul_int<N: FixedPointOperand>(self, n: N) -> Option<N> { ... } fn saturating_mul_int<N: FixedPointOperand>(self, n: N) -> N { ... } fn checked_div_int<N: FixedPointOperand>(self, d: N) -> Option<N> { ... } fn saturating_div_int<N: FixedPointOperand>(self, d: N) -> N { ... } fn saturating_mul_acc_int<N: FixedPointOperand>(self, n: N) -> N { ... } fn saturating_abs(self) -> Self { ... } fn reciprocal(self) -> Option<Self> { ... } fn is_one(&self) -> bool { ... } fn is_positive(self) -> bool { ... } fn is_negative(self) -> bool { ... } fn trunc(self) -> Self { ... } fn frac(self) -> Self { ... } fn ceil(self) -> Self { ... } fn floor(self) -> Self { ... } fn round(self) -> Self { ... }
}
Expand description

Something that implements a decimal fixed point number.

The precision is given by Self::DIV, i.e. 1 / DIV can be represented.

Each type can store numbers from Self::Inner::min_value() / Self::DIV to Self::Inner::max_value() / Self::DIV. This is also referred to as the accuracy of the type in the documentation.

Required Associated Types§

The underlying data type used for this fixed point number.

Required Associated Constants§

Precision of this fixed point implementation. It should be a power of 10.

Indicates if this fixed point implementation is signed or not.

Required Methods§

Builds this type from an integer number.

Consumes self and returns the inner raw value.

Provided Methods§

Precision of this fixed point implementation.

Creates self from an integer number int.

Returns Self::max or Self::min if int exceeds accuracy.

Examples found in repository?
src/fixed_point.rs (line 310)
309
310
311
312
313
314
315
316
317
318
	fn round(self) -> Self {
		let n = self.frac().saturating_mul(Self::saturating_from_integer(10));
		if n < Self::saturating_from_integer(5) {
			self.trunc()
		} else if self.is_positive() {
			self.saturating_add(Self::one()).trunc()
		} else {
			self.saturating_sub(Self::one()).trunc()
		}
	}

Creates self from an integer number int.

Returns None if int exceeds accuracy.

Creates self from a rational number. Equal to n / d.

Panics if d = 0. Returns Self::max or Self::min if n / d exceeds accuracy.

Creates self from a rational number. Equal to n / d.

Returns None if d == 0 or n / d exceeds accuracy.

Examples found in repository?
src/fixed_point.rs (line 136)
132
133
134
135
136
137
	fn saturating_from_rational<N: FixedPointOperand, D: FixedPointOperand>(n: N, d: D) -> Self {
		if d == D::zero() {
			panic!("attempt to divide by zero")
		}
		Self::checked_from_rational(n, d).unwrap_or_else(|| to_bound(n, d))
	}

Checked multiplication for integer type N. Equal to self * n.

Returns None if the result does not fit in N.

Examples found in repository?
src/fixed_point.rs (line 185)
184
185
186
	fn saturating_mul_int<N: FixedPointOperand>(self, n: N) -> N {
		self.checked_mul_int(n).unwrap_or_else(|| to_bound(self.into_inner(), n))
	}

Saturating multiplication for integer type N. Equal to self * n.

Returns N::min or N::max if the result does not fit in N.

Examples found in repository?
src/fixed_point.rs (line 218)
216
217
218
219
220
221
222
	fn saturating_mul_acc_int<N: FixedPointOperand>(self, n: N) -> N {
		if self.is_negative() && n > N::zero() {
			n.saturating_sub(Self::zero().saturating_sub(self).saturating_mul_int(n))
		} else {
			self.saturating_mul_int(n).saturating_add(n)
		}
	}

Checked division for integer type N. Equal to self / d.

Returns None if the result does not fit in N or d == 0.

Examples found in repository?
src/fixed_point.rs (line 209)
205
206
207
208
209
210
	fn saturating_div_int<N: FixedPointOperand>(self, d: N) -> N {
		if d == N::zero() {
			panic!("attempt to divide by zero")
		}
		self.checked_div_int(d).unwrap_or_else(|| to_bound(self.into_inner(), d))
	}

Saturating division for integer type N. Equal to self / d.

Panics if d == 0. Returns N::min or N::max if the result does not fit in N.

Saturating multiplication for integer type N, adding the result back. Equal to self * n + n.

Returns N::min or N::max if the multiplication or final result does not fit in N.

Saturating absolute value.

Returns Self::max if self == Self::min.

Examples found in repository?
src/fixed_point.rs (line 278)
272
273
274
275
276
277
278
279
280
	fn frac(self) -> Self {
		let integer = self.trunc();
		let fractional = self.saturating_sub(integer);
		if integer == Self::zero() {
			fractional
		} else {
			fractional.saturating_abs()
		}
	}

Takes the reciprocal (inverse). Equal to 1 / self.

Returns None if self = 0.

Checks if the number is one.

Returns true if self is positive and false if the number is zero or negative.

Examples found in repository?
src/fixed_point.rs (line 313)
309
310
311
312
313
314
315
316
317
318
	fn round(self) -> Self {
		let n = self.frac().saturating_mul(Self::saturating_from_integer(10));
		if n < Self::saturating_from_integer(5) {
			self.trunc()
		} else if self.is_positive() {
			self.saturating_add(Self::one()).trunc()
		} else {
			self.saturating_sub(Self::one()).trunc()
		}
	}

Returns true if self is negative and false if the number is zero or positive.

Examples found in repository?
src/fixed_point.rs (line 217)
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
	fn saturating_mul_acc_int<N: FixedPointOperand>(self, n: N) -> N {
		if self.is_negative() && n > N::zero() {
			n.saturating_sub(Self::zero().saturating_sub(self).saturating_mul_int(n))
		} else {
			self.saturating_mul_int(n).saturating_add(n)
		}
	}

	/// Saturating absolute value.
	///
	/// Returns `Self::max` if `self == Self::min`.
	fn saturating_abs(self) -> Self {
		let inner = self.into_inner();
		if inner >= Self::Inner::zero() {
			self
		} else {
			Self::from_inner(inner.checked_neg().unwrap_or_else(Self::Inner::max_value))
		}
	}

	/// Takes the reciprocal (inverse). Equal to `1 / self`.
	///
	/// Returns `None` if `self = 0`.
	fn reciprocal(self) -> Option<Self> {
		Self::one().checked_div(&self)
	}

	/// Checks if the number is one.
	fn is_one(&self) -> bool {
		self.into_inner() == Self::Inner::one()
	}

	/// Returns `true` if `self` is positive and `false` if the number is zero or negative.
	fn is_positive(self) -> bool {
		self.into_inner() > Self::Inner::zero()
	}

	/// Returns `true` if `self` is negative and `false` if the number is zero or positive.
	fn is_negative(self) -> bool {
		self.into_inner() < Self::Inner::zero()
	}

	/// Returns the integer part.
	fn trunc(self) -> Self {
		self.into_inner()
			.checked_div(&Self::DIV)
			.expect("panics only if DIV is zero, DIV is not zero; qed")
			.checked_mul(&Self::DIV)
			.map(Self::from_inner)
			.expect("can not overflow since fixed number is >= integer part")
	}

	/// Returns the fractional part.
	///
	/// Note: the returned fraction will be non-negative for negative numbers,
	/// except in the case where the integer part is zero.
	fn frac(self) -> Self {
		let integer = self.trunc();
		let fractional = self.saturating_sub(integer);
		if integer == Self::zero() {
			fractional
		} else {
			fractional.saturating_abs()
		}
	}

	/// Returns the smallest integer greater than or equal to a number.
	///
	/// Saturates to `Self::max` (truncated) if the result does not fit.
	fn ceil(self) -> Self {
		if self.is_negative() {
			self.trunc()
		} else if self.frac() == Self::zero() {
			self
		} else {
			self.saturating_add(Self::one()).trunc()
		}
	}

	/// Returns the largest integer less than or equal to a number.
	///
	/// Saturates to `Self::min` (truncated) if the result does not fit.
	fn floor(self) -> Self {
		if self.is_negative() {
			self.saturating_sub(Self::one()).trunc()
		} else {
			self.trunc()
		}
	}

Returns the integer part.

Examples found in repository?
src/fixed_point.rs (line 273)
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
	fn frac(self) -> Self {
		let integer = self.trunc();
		let fractional = self.saturating_sub(integer);
		if integer == Self::zero() {
			fractional
		} else {
			fractional.saturating_abs()
		}
	}

	/// Returns the smallest integer greater than or equal to a number.
	///
	/// Saturates to `Self::max` (truncated) if the result does not fit.
	fn ceil(self) -> Self {
		if self.is_negative() {
			self.trunc()
		} else if self.frac() == Self::zero() {
			self
		} else {
			self.saturating_add(Self::one()).trunc()
		}
	}

	/// Returns the largest integer less than or equal to a number.
	///
	/// Saturates to `Self::min` (truncated) if the result does not fit.
	fn floor(self) -> Self {
		if self.is_negative() {
			self.saturating_sub(Self::one()).trunc()
		} else {
			self.trunc()
		}
	}

	/// Returns the number rounded to the nearest integer. Rounds half-way cases away from 0.0.
	///
	/// Saturates to `Self::min` or `Self::max` (truncated) if the result does not fit.
	fn round(self) -> Self {
		let n = self.frac().saturating_mul(Self::saturating_from_integer(10));
		if n < Self::saturating_from_integer(5) {
			self.trunc()
		} else if self.is_positive() {
			self.saturating_add(Self::one()).trunc()
		} else {
			self.saturating_sub(Self::one()).trunc()
		}
	}

Returns the fractional part.

Note: the returned fraction will be non-negative for negative numbers, except in the case where the integer part is zero.

Examples found in repository?
src/fixed_point.rs (line 288)
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
	fn ceil(self) -> Self {
		if self.is_negative() {
			self.trunc()
		} else if self.frac() == Self::zero() {
			self
		} else {
			self.saturating_add(Self::one()).trunc()
		}
	}

	/// Returns the largest integer less than or equal to a number.
	///
	/// Saturates to `Self::min` (truncated) if the result does not fit.
	fn floor(self) -> Self {
		if self.is_negative() {
			self.saturating_sub(Self::one()).trunc()
		} else {
			self.trunc()
		}
	}

	/// Returns the number rounded to the nearest integer. Rounds half-way cases away from 0.0.
	///
	/// Saturates to `Self::min` or `Self::max` (truncated) if the result does not fit.
	fn round(self) -> Self {
		let n = self.frac().saturating_mul(Self::saturating_from_integer(10));
		if n < Self::saturating_from_integer(5) {
			self.trunc()
		} else if self.is_positive() {
			self.saturating_add(Self::one()).trunc()
		} else {
			self.saturating_sub(Self::one()).trunc()
		}
	}

Returns the smallest integer greater than or equal to a number.

Saturates to Self::max (truncated) if the result does not fit.

Returns the largest integer less than or equal to a number.

Saturates to Self::min (truncated) if the result does not fit.

Returns the number rounded to the nearest integer. Rounds half-way cases away from 0.0.

Saturates to Self::min or Self::max (truncated) if the result does not fit.

Implementors§