Struct Decimal
pub struct Decimal(/* private fields */);
Expand description
A fixed-point decimal number type.
This type should be used for precise arithmetic operations on numbers represented in base 10. A typical use case is representing currency.
§Example
Decimal: #(decimal("0.1") + decimal("0.2")) \
Float: #(0.1 + 0.2)
§Construction and casts
To create a decimal number, use the {decimal(string)}
constructor, such as
in {decimal("3.141592653")}
(note the double quotes!). This
constructor preserves all given fractional digits, provided they are
representable as per the limits specified below (otherwise, an error is
raised).
You can also convert any integer to a decimal with the
{decimal(int)}
constructor, e.g. {decimal(59)}
. However, note that
constructing a decimal from a floating-point number, while
supported, is an imprecise conversion and therefore discouraged. A
warning will be raised if Typst detects that there was an accidental float
to decimal
cast through its constructor, e.g. if writing {decimal(3.14)}
(note the lack of double quotes, indicating this is an accidental float
cast and therefore imprecise). It is recommended to use strings for
constant decimal values instead (e.g. {decimal("3.14")}
).
The precision of a float
to decimal
cast can be slightly improved by
rounding the result to 15 digits with calc.round
, but there
are still no precision guarantees for that kind of conversion.
§Operations
Basic arithmetic operations are supported on two decimals and on pairs of decimals and integers.
Built-in operations between float
and decimal
are not supported in order
to guard against accidental loss of precision. They will raise an error
instead.
Certain calc
functions, such as trigonometric functions and power between
two real numbers, are also only supported for float
(although raising
decimal
to integer exponents is supported). You can opt into potentially
imprecise operations with the {float(decimal)}
constructor, which casts
the decimal
number into a float
, allowing for operations without
precision guarantees.
§Displaying decimals
To display a decimal, simply insert the value into the document. To only display a certain number of digits, round the decimal first. Localized formatting of decimals and other numbers is not yet supported, but planned for the future.
You can convert decimals to strings using the str
constructor. This way,
you can post-process the displayed representation, e.g. to replace the
period with a comma (as a stand-in for proper built-in localization to
languages that use the comma).
§Precision and limits
A decimal
number has a limit of 28 to 29 significant base-10 digits. This
includes the sum of digits before and after the decimal point. As such,
numbers with more fractional digits have a smaller range. The maximum and
minimum decimal
numbers have a value of {79228162514264337593543950335}
and {-79228162514264337593543950335}
respectively. In contrast with
[float
], this type does not support infinity or NaN, so overflowing or
underflowing operations will raise an error.
Typical operations between decimal
numbers, such as addition,
multiplication, and power to an integer, will be highly precise
due to their fixed-point representation. Note, however, that multiplication
and division may not preserve all digits in some edge cases: while they are
considered precise, digits past the limits specified above are rounded off
and lost, so some loss of precision beyond the maximum representable digits
is possible. Note that this behavior can be observed not only when dividing,
but also when multiplying by numbers between 0 and 1, as both operations can
push a number’s fractional digits beyond the limits described above, leading
to rounding. When those two operations do not surpass the digit limits, they
are fully precise.
Implementations§
§impl Decimal
impl Decimal
pub const ZERO: Decimal
pub const ONE: Decimal
pub const MIN: Decimal
pub const MAX: Decimal
pub const fn is_negative(self) -> bool
pub const fn is_negative(self) -> bool
Whether this decimal value is negative.
pub fn is_integer(self) -> bool
pub fn is_integer(self) -> bool
Whether this decimal has fractional part equal to zero (is an integer).
pub fn floor(self) -> Decimal
pub fn floor(self) -> Decimal
Computes the largest integer less than or equal to this decimal.
A decimal is returned as this may not be within i64
’s range of
values.
pub fn ceil(self) -> Decimal
pub fn ceil(self) -> Decimal
Computes the smallest integer greater than or equal to this decimal.
A decimal is returned as this may not be within i64
’s range of
values.
pub fn fract(self) -> Decimal
pub fn fract(self) -> Decimal
Returns the fractional part of this decimal (with the integer part set to zero).
pub fn round(self, digits: i32) -> Option<Decimal>
pub fn round(self, digits: i32) -> Option<Decimal>
Rounds this decimal up to the specified amount of digits with the traditional rounding rules, using the “midpoint away from zero” strategy (6.5 -> 7, -6.5 -> -7).
If given a negative amount of digits, rounds to integer digits instead with the same rounding strategy. For example, rounding to -3 digits will turn 34567.89 into 35000.00 and -34567.89 into -35000.00.
Note that this can return None
when using negative digits where the
rounded number would overflow the available range for decimals.
pub fn checked_add(self, other: Decimal) -> Option<Decimal>
pub fn checked_add(self, other: Decimal) -> Option<Decimal>
Attempts to add two decimals.
Returns None
on overflow or underflow.
pub fn checked_sub(self, other: Decimal) -> Option<Decimal>
pub fn checked_sub(self, other: Decimal) -> Option<Decimal>
Attempts to subtract a decimal from another.
Returns None
on overflow or underflow.
pub fn checked_mul(self, other: Decimal) -> Option<Decimal>
pub fn checked_mul(self, other: Decimal) -> Option<Decimal>
Attempts to multiply two decimals.
Returns None
on overflow or underflow.
pub fn checked_div(self, other: Decimal) -> Option<Decimal>
pub fn checked_div(self, other: Decimal) -> Option<Decimal>
Attempts to divide two decimals.
Returns None
if other
is zero, as well as on overflow or underflow.
pub fn checked_div_euclid(self, other: Decimal) -> Option<Decimal>
pub fn checked_div_euclid(self, other: Decimal) -> Option<Decimal>
Attempts to obtain the quotient of Euclidean division between two
decimals. Implemented similarly to f64::div_euclid
.
The returned quotient is truncated and adjusted if the remainder was negative.
Returns None
if other
is zero, as well as on overflow or underflow.
pub fn checked_rem_euclid(self, other: Decimal) -> Option<Decimal>
pub fn checked_rem_euclid(self, other: Decimal) -> Option<Decimal>
Attempts to obtain the remainder of Euclidean division between two
decimals. Implemented similarly to f64::rem_euclid
.
The returned decimal r
is non-negative within the range
0.0 <= r < other.abs()
.
Returns None
if other
is zero, as well as on overflow or underflow.
pub fn checked_rem(self, other: Decimal) -> Option<Decimal>
pub fn checked_rem(self, other: Decimal) -> Option<Decimal>
Attempts to calculate the remainder of the division of two decimals.
Returns None
if other
is zero, as well as on overflow or underflow.
pub fn checked_powi(self, other: i64) -> Option<Decimal>
pub fn checked_powi(self, other: i64) -> Option<Decimal>
Attempts to take one decimal to the power of an integer.
Returns None
for invalid operands, as well as on overflow or
underflow.
§impl Decimal
impl Decimal
pub fn construct(
engine: &mut Engine<'_>,
value: Spanned<ToDecimal>,
) -> Result<Decimal, EcoVec<SourceDiagnostic>>
pub fn construct( engine: &mut Engine<'_>, value: Spanned<ToDecimal>, ) -> Result<Decimal, EcoVec<SourceDiagnostic>>
Converts a value to a decimal
.
It is recommended to use a string to construct the decimal number, or an
integer (if desired). The string must contain a number in the
format {"3.14159"}
(or {"-3.141519"}
for negative numbers). The
fractional digits are fully preserved; if that’s not possible due to the
limit of significant digits (around 28 to 29) having been reached, an
error is raised as the given decimal number wouldn’t be representable.
While this constructor can be used with floating-point numbers
to cast them to decimal
, doing so is discouraged as this cast is
inherently imprecise. It is easy to accidentally perform this cast by
writing {decimal(1.234)}
(note the lack of double quotes), which is
why Typst will emit a warning in that case. Please write
{decimal("1.234")}
instead for that particular case (initialization of
a constant decimal). Also note that floats that are NaN or infinite
cannot be cast to decimals and will raise an error.
#decimal("1.222222222222222")
Trait Implementations§
§impl FromValue for Decimal
impl FromValue for Decimal
§fn from_value(value: Value) -> Result<Decimal, HintedString>
fn from_value(value: Value) -> Result<Decimal, HintedString>
Self
.§impl NativeScope for Decimal
impl NativeScope for Decimal
§fn constructor() -> Option<&'static NativeFuncData>
fn constructor() -> Option<&'static NativeFuncData>
§impl NativeType for Decimal
impl NativeType for Decimal
§impl Ord for Decimal
impl Ord for Decimal
§impl PartialOrd for Decimal
impl PartialOrd for Decimal
§impl Reflect for Decimal
impl Reflect for Decimal
§fn error(found: &Value) -> HintedString
fn error(found: &Value) -> HintedString
impl Copy for Decimal
impl Eq for Decimal
impl StructuralPartialEq for Decimal
Auto Trait Implementations§
impl Freeze for Decimal
impl RefUnwindSafe for Decimal
impl Send for Decimal
impl Sync for Decimal
impl Unpin for Decimal
impl UnwindSafe for Decimal
Blanket Implementations§
Source§impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
Source§fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
Source§fn adapt_into(self) -> D
fn adapt_into(self) -> D
§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
§type ArchivedMetadata = ()
type ArchivedMetadata = ()
§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
Source§fn arrays_from(colors: C) -> T
fn arrays_from(colors: C) -> T
Source§impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
Source§fn arrays_into(self) -> C
fn arrays_into(self) -> C
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CallHasher for T
impl<T> CallHasher for T
Source§impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
Source§type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
parameters
when converting.Source§fn cam16_into_unclamped(
self,
parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>,
) -> T
fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T
self
into C
, using the provided parameters.Source§impl<T> CheckedAs for T
impl<T> CheckedAs for T
Source§fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
Source§impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
Source§fn checked_cast_from(src: Src) -> Option<Dst>
fn checked_cast_from(src: Src) -> Option<Dst>
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
Source§impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
Source§fn components_from(colors: C) -> T
fn components_from(colors: C) -> T
§impl<F, W, T, D> Deserialize<With<T, W>, D> for F
impl<F, W, T, D> Deserialize<With<T, W>, D> for F
§fn deserialize(
&self,
deserializer: &mut D,
) -> Result<With<T, W>, <D as Fallible>::Error>
fn deserialize( &self, deserializer: &mut D, ) -> Result<With<T, W>, <D as Fallible>::Error>
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.§impl<T> Filterable for T
impl<T> Filterable for T
Source§impl<T> FromAngle<T> for T
impl<T> FromAngle<T> for T
Source§fn from_angle(angle: T) -> T
fn from_angle(angle: T) -> T
angle
.Source§impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
Source§fn from_stimulus(other: U) -> T
fn from_stimulus(other: U) -> T
other
into Self
, while performing the appropriate scaling,
rounding and clamping.§impl<T> FromValue<Spanned<Value>> for Twhere
T: FromValue,
impl<T> FromValue<Spanned<Value>> for Twhere
T: FromValue,
§fn from_value(value: Spanned<Value>) -> Result<T, HintedString>
fn from_value(value: Spanned<Value>) -> Result<T, HintedString>
Self
.Source§impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
Source§fn into_angle(self) -> U
fn into_angle(self) -> U
T
.Source§impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
Source§type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
parameters
when converting.Source§fn into_cam16_unclamped(
self,
parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>,
) -> T
fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T
self
into C
, using the provided parameters.Source§impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
Source§fn into_color(self) -> U
fn into_color(self) -> U
Source§impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
Source§fn into_color_unclamped(self) -> U
fn into_color_unclamped(self) -> U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoResult for Twhere
T: IntoValue,
impl<T> IntoResult for Twhere
T: IntoValue,
§fn into_result(self, _: Span) -> Result<Value, EcoVec<SourceDiagnostic>>
fn into_result(self, _: Span) -> Result<Value, EcoVec<SourceDiagnostic>>
Source§impl<T> IntoStimulus<T> for T
impl<T> IntoStimulus<T> for T
Source§fn into_stimulus(self) -> T
fn into_stimulus(self) -> T
self
into T
, while performing the appropriate scaling,
rounding and clamping.§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T> OverflowingAs for T
impl<T> OverflowingAs for T
Source§fn overflowing_as<Dst>(self) -> (Dst, bool)where
T: OverflowingCast<Dst>,
fn overflowing_as<Dst>(self) -> (Dst, bool)where
T: OverflowingCast<Dst>,
Source§impl<Src, Dst> OverflowingCastFrom<Src> for Dstwhere
Src: OverflowingCast<Dst>,
impl<Src, Dst> OverflowingCastFrom<Src> for Dstwhere
Src: OverflowingCast<Dst>,
Source§fn overflowing_cast_from(src: Src) -> (Dst, bool)
fn overflowing_cast_from(src: Src) -> (Dst, bool)
§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> SaturatingAs for T
impl<T> SaturatingAs for T
Source§fn saturating_as<Dst>(self) -> Dstwhere
T: SaturatingCast<Dst>,
fn saturating_as<Dst>(self) -> Dstwhere
T: SaturatingCast<Dst>,
Source§impl<Src, Dst> SaturatingCastFrom<Src> for Dstwhere
Src: SaturatingCast<Dst>,
impl<Src, Dst> SaturatingCastFrom<Src> for Dstwhere
Src: SaturatingCast<Dst>,
Source§fn saturating_cast_from(src: Src) -> Dst
fn saturating_cast_from(src: Src) -> Dst
Source§impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
Source§type Error = <C as TryFromComponents<T>>::Error
type Error = <C as TryFromComponents<T>>::Error
try_into_colors
fails to cast.Source§fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
Source§impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
Source§fn try_into_color(self) -> Result<U, OutOfBounds<U>>
fn try_into_color(self) -> Result<U, OutOfBounds<U>>
OutOfBounds
error is returned which contains
the unclamped color. Read more