struct BigDecimal

Overview

A BigDecimal can represent arbitrarily large precision decimals.

It is internally represented by a pair of BigInt and UInt64: value and scale. Value contains the actual value, and scale tells the decimal point place. E.g. when value is 1234 and scale 2, the result is 12.34.

NOTE To use BigDecimal, you must explicitly import it with require "big"

The general idea and some of the arithmetic algorithms were adapted from the MIT/APACHE-licensed bigdecimal-rs.

Included Modules

Defined in:

big.cr
big/big_decimal.cr
big/number.cr

Constant Summary

DEFAULT_MAX_DIV_ITERATIONS = 100_u64

DEPRECATED Use DEFAULT_PRECISION instead

DEFAULT_PRECISION = 100_u64

Constructors

Instance Method Summary

Instance methods inherited from module Comparable(BigDecimal)

<(other : T) : Bool <, <=(other : T) <=, <=>(other : T) <=>, ==(other : T) ==, >(other : T) : Bool >, >=(other : T) >=, clamp(min, max)
clamp(range : Range)
clamp

Instance methods inherited from module Comparable(BigRational)

<(other : T) : Bool <, <=(other : T) <=, <=>(other : T) <=>, ==(other : T) ==, >(other : T) : Bool >, >=(other : T) >=, clamp(min, max)
clamp(range : Range)
clamp

Instance methods inherited from module Comparable(Float)

<(other : T) : Bool <, <=(other : T) <=, <=>(other : T) <=>, ==(other : T) ==, >(other : T) : Bool >, >=(other : T) >=, clamp(min, max)
clamp(range : Range)
clamp

Instance methods inherited from module Comparable(Int)

<(other : T) : Bool <, <=(other : T) <=, <=>(other : T) <=>, ==(other : T) ==, >(other : T) : Bool >, >=(other : T) >=, clamp(min, max)
clamp(range : Range)
clamp

Instance methods inherited from struct Number

*(other : BigFloat) : BigFloat
*(other : Complex) : Complex
*
, +(other : BigFloat)
+(other : Complex) : Complex
+
+
, -(other : BigFloat)
-(other : Complex) : Complex
-
, /(other : BigFloat) : BigFloat
/(other : Complex) : Complex
/
, //(other) //, <=>(other) : Int32 | Nil <=>, ==(other : Complex) ==, abs : self abs, abs2 abs2, cis : Complex cis, divmod(number) divmod, format(io : IO, separator = '.', delimiter = ',', decimal_places : Int | Nil = nil, *, group : Int = 3, only_significant : Bool = false) : Nil
format(separator = '.', delimiter = ',', decimal_places : Int | Nil = nil, *, group : Int = 3, only_significant : Bool = false) : String
format
, humanize(io : IO, precision = 3, separator = '.', delimiter = ',', *, base = 10 ** 3, significant = true, prefixes : Indexable = SI_PREFIXES) : Nil
humanize(io : IO, precision = 3, separator = '.', delimiter = ',', *, base = 10 ** 3, significant = true, prefixes : Proc) : Nil
humanize(precision = 3, separator = '.', delimiter = ',', *, base = 10 ** 3, significant = true, prefixes = SI_PREFIXES) : String
humanize(io : IO, precision = 3, separator = '.', delimiter = ',', *, base = 10 ** 3, significant = true, &prefixes : Int32, Float64 -> Tuple(Int32, _) | Tuple(Int32, _, Bool)) : Nil
humanize(precision = 3, separator = '.', delimiter = ',', *, base = 10 ** 3, significant = true, &) : String
humanize(precision = 3, separator = '.', delimiter = ',', *, base = 10 ** 3, significant = true, prefixes : Proc) : String
humanize
, i : Complex i, negative? : Bool negative?, positive? : Bool positive?, round(mode : RoundingMode = :ties_even) : self
round(digits : Number, base = 10, *, mode : RoundingMode = :ties_even)
round
, sign : Int32 sign, significant(digits, base = 10) significant, step(*, to limit = nil, exclusive : Bool = false, &) : Nil
step(*, to limit = nil, exclusive : Bool = false)
step
, to_big_f : BigFloat to_big_f, to_c : Complex to_c, to_yaml(yaml : YAML::Nodes::Builder) : Nil to_yaml, zero? : Bool zero?

Constructor methods inherited from struct Number

additive_identity : self additive_identity, multiplicative_identity : self multiplicative_identity, zero : self zero

Class methods inherited from struct Number

si_prefix(magnitude : Int, prefixes = SI_PREFIXES) : Char | Nil si_prefix

Instance methods inherited from module Comparable(BigFloat)

<(other : T) : Bool <, <=(other : T) <=, <=>(other : T) <=>, ==(other : T) ==, >(other : T) : Bool >, >=(other : T) >=, clamp(min, max)
clamp(range : Range)
clamp

Instance methods inherited from module Steppable

step(*, to limit = nil, by step, exclusive : Bool = false, &) : Nil
step(*, to limit = nil, by step, exclusive : Bool = false)
step

Instance methods inherited from module Comparable(Number)

<(other : T) : Bool <, <=(other : T) <=, <=>(other : T) <=>, ==(other : T) ==, >(other : T) : Bool >, >=(other : T) >=, clamp(min, max)
clamp(range : Range)
clamp

Instance methods inherited from struct Value

==(other : JSON::Any)
==(other : YAML::Any)
==(other)
==
, dup dup

Instance methods inherited from class Object

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other)
===
, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash
hash
, in?(collection : Object) : Bool
in?(*values : Object) : Bool
in?
, inspect(io : IO) : Nil
inspect : String
inspect
, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil!
not_nil!
, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String
to_json
, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil
to_pretty_json
, to_s(io : IO) : Nil
to_s : String
to_s
, to_yaml(io : IO) : Nil
to_yaml : String
to_yaml
, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

Class methods inherited from class Object

from_json(string_or_io, root : String)
from_json(string_or_io)
from_json
, from_yaml(string_or_io : String | IO) from_yaml

Constructor Detail

def self.new(value : BigInt, scale : UInt64) #

Creates a new BigDecimal from BigInt value and UInt64 scale, which matches the internal representation.


[View source]
def self.new(num : Float) #

Creates a new BigDecimal from Float.

NOTE Floats are fundamentally less precise than BigDecimals, which makes initialization from them risky.


[View source]
def self.new(num : BigRational) #

Creates a new BigDecimal from BigRational.

NOTE BigRational are fundamentally more precise than BigDecimals, which makes initialization from them risky.


[View source]
def self.new(num : BigDecimal) #

Returns num. Useful for generic code that does T.new(...) with T being a Number.


[View source]
def self.new(num : Int = 0, scale : Int = 0) #

Creates a new BigDecimal from Int.


[View source]
def self.new(str : String) #

Creates a new BigDecimal from a String.

Allows only valid number strings with an optional negative sign.


[View source]

Instance Method Detail

def %(other : BigDecimal) : BigDecimal #

[View source]
def %(other : Int) #

[View source]
def *(other : BigDecimal) : BigDecimal #

[View source]
def *(other : Number) : BigDecimal #

[View source]
def **(other : Int) : BigDecimal #

Raises the decimal to the otherth power

require "big"

BigDecimal.new(1234, 2) ** 2 # => 152.2756

[View source]
def +(other : BigDecimal) : BigDecimal #

[View source]
def +(other : Number) : BigDecimal #

[View source]
def -(other : BigDecimal) : BigDecimal #

[View source]
def -(other : Number) : BigDecimal #

[View source]
def - : BigDecimal #

[View source]
def /(other : BigDecimal) : BigDecimal #

[View source]
def /(other : BigInt) : BigDecimal #

[View source]
def /(other : BigFloat) : BigDecimal #

[View source]
def /(other : BigRational) : BigRational #

[View source]
def /(other : Int8) : BigDecimal #

[View source]
def /(other : UInt8) : BigDecimal #

[View source]
def /(other : Int16) : BigDecimal #

[View source]
def /(other : UInt16) : BigDecimal #

[View source]
def /(other : Int32) : BigDecimal #

[View source]
def /(other : UInt32) : BigDecimal #

[View source]
def /(other : Int64) : BigDecimal #

[View source]
def /(other : UInt64) : BigDecimal #

[View source]
def /(other : Int128) : BigDecimal #

[View source]
def /(other : UInt128) : BigDecimal #

[View source]
def /(other : Float32) : BigDecimal #

[View source]
def /(other : Float64) : BigDecimal #

[View source]
def <=>(other : BigDecimal) : Int32 #
Description copied from module Comparable(BigDecimal)

The comparison operator. Returns 0 if the two objects are equal, a negative number if this object is considered less than other, a positive number if this object is considered greater than other, or nil if the two objects are not comparable.

Subclasses define this method to provide class-specific ordering.

The comparison operator is usually used to sort values:

# Sort in a descending way:
[3, 1, 2].sort { |x, y| y <=> x } # => [3, 2, 1]

# Sort in an ascending way:
[3, 1, 2].sort { |x, y| x <=> y } # => [1, 2, 3]

[View source]
def <=>(other : BigRational) : Int32 #

[View source]
def <=>(other : Float::Primitive) : Int32 | Nil #

[View source]
def <=>(other : BigFloat) : Int32 #

[View source]
def <=>(other : Int) #

[View source]
def ==(other : BigDecimal) : Bool #
Description copied from module Comparable(BigDecimal)

Compares this object to other based on the receiver’s <=> method, returning true if it returns 0.

Also returns true if this and other are the same object.


[View source]
def ceil : BigDecimal #

Rounds towards positive infinity.


[View source]
def clone #

[View source]
def div(other : BigDecimal, precision = DEFAULT_PRECISION) : BigDecimal #

Divides self with another BigDecimal, with an optionally configurable precision.

When the division is inexact, the returned value rounds towards negative infinity, and its scale is never greater than scale - other.scale + precision.

BigDecimal.new(1).div(BigDecimal.new(2))    # => BigDecimal(@value=5, @scale=2)
BigDecimal.new(1).div(BigDecimal.new(3), 5) # => BigDecimal(@value=33333, @scale=5)

[View source]
def div(other : BigDecimal, *, max_div_iterations = DEFAULT_MAX_DIV_ITERATIONS) : BigDecimal #

Divides self with another BigDecimal, with an optionally configurable precision.

When the division is inexact, the returned value rounds towards negative infinity, and its scale is never greater than scale - other.scale + precision.

BigDecimal.new(1).div(BigDecimal.new(2))    # => BigDecimal(@value=5, @scale=2)
BigDecimal.new(1).div(BigDecimal.new(3), 5) # => BigDecimal(@value=33333, @scale=5)

DEPRECATED Use #div(other : BigDecimal, precision = DEFAULT_PRECISION) instead


[View source]
def floor : BigDecimal #

Rounds towards negative infinity.


[View source]
def hash(hasher) #
Description copied from class Object

Appends this object's value to hasher, and returns the modified hasher.

Usually the macro def_hash can be used to generate this method. Otherwise, invoke #hash(hasher) on each object's instance variables to accumulate the result:

def hash(hasher)
  hasher = @some_ivar.hash(hasher)
  hasher = @some_other_ivar.hash(hasher)
  hasher
end

[View source]
def normalize_quotient(other : BigDecimal, quotient : BigInt) : BigInt #

Returns the quotient as absolutely negative if self and other have different signs, otherwise returns the quotient.


[View source]
def round(digits : Number, base = 10, *, mode : RoundingMode = :ties_even) : BigDecimal #
Description copied from struct Number

Rounds this number to a given precision.

Rounds to the specified number of digits after the decimal place, (or before if negative), in base base.

The rounding mode controls the direction of the rounding. The default is RoundingMode::TIES_EVEN which rounds to the nearest integer, with ties (fractional value of 0.5) being rounded to the even neighbor (Banker's rounding).

-1763.116.round(2) # => -1763.12

[View source]
def round_away : BigDecimal #

Rounds towards the nearest integer. If both neighboring integers are equidistant, rounds away from zero.


[View source]
def round_even : BigDecimal #

Rounds towards the nearest integer. If both neighboring integers are equidistant, rounds towards the even neighbor (Banker's rounding).


[View source]
def scale : UInt64 #

[View source]
def scale_to(new_scale : BigDecimal) : BigDecimal #

Scales a BigDecimal to another BigDecimal, so they can be computed easier.


[View source]
def to_big_d #

[View source]
def to_big_f #

Converts to BigFloat.


[View source]
def to_big_i : BigInt #

Converts to BigInt. Truncates anything on the right side of the decimal point.


[View source]
def to_big_r : BigRational #

[View source]
def to_f : Float64 #

Converts to Float64. Raises OverflowError in case of overflow.


[View source]
def to_f! : Float64 #

Converts to Float64. In case of overflow a wrapping is performed.


[View source]
def to_f32 : Float32 #

Converts to Float32. Raises OverflowError in case of overflow.


[View source]
def to_f32! #

Converts to Float32. In case of overflow a wrapping is performed.


[View source]
def to_f64 : Float64 #

Converts to Float64. Raises OverflowError in case of overflow.


[View source]
def to_f64! : Float64 #

Converts to Float64. In case of overflow a wrapping is performed.


[View source]
def to_i : Int32 #

Converts to Int32. Truncates anything on the right side of the decimal point. Raises OverflowError in case of overflow.


[View source]
def to_i! : Int32 #

Converts to Int32. Truncates anything on the right side of the decimal point. In case of overflow a wrapping is performed.


[View source]
def to_i16 : Int16 #

Converts to Int16. Truncates anything on the right side of the decimal point. Raises OverflowError in case of overflow.


[View source]
def to_i16! #

Converts to Int16. Truncates anything on the right side of the decimal point. In case of overflow a wrapping is performed.


[View source]
def to_i32 : Int32 #

Converts to Int32. Truncates anything on the right side of the decimal point. Raises OverflowError in case of overflow.


[View source]
def to_i32! : Int32 #

Converts to Int32. Truncates anything on the right side of the decimal point. In case of overflow a wrapping is performed.


[View source]
def to_i64 : Int64 #

Converts to Int64. Truncates anything on the right side of the decimal point. Raises OverflowError in case of overflow.


[View source]
def to_i64! #

Converts to Int64. Truncates anything on the right side of the decimal point. In case of overflow a wrapping is performed.


[View source]
def to_i8 : Int8 #

Converts to Int8. Truncates anything on the right side of the decimal point. Raises OverflowError in case of overflow.


[View source]
def to_i8! #

Converts to Int8. Truncates anything on the right side of the decimal point. In case of overflow a wrapping is performed.


[View source]
def to_s(io : IO) : Nil #
Description copied from class Object

Prints a nicely readable and concise string representation of this object, typically intended for users, to io.

This method is called when an object is interpolated in a string literal:

"foo #{bar} baz" # calls bar.to_io with the builder for this string

IO#<< calls this method to append an object to itself:

io << bar # calls bar.to_s(io)

Thus implementations must not interpolate self in a string literal or call io << self which both would lead to an endless loop.

Also see #inspect(IO).


[View source]
def to_u : UInt32 #

Converts to UInt32. Truncates anything on the right side of the decimal point. Raises OverflowError in case of overflow.


[View source]
def to_u! : UInt32 #

Converts to UInt32. Truncates anything on the right side of the decimal point, converting negative to positive. In case of overflow a wrapping is performed.


[View source]
def to_u16 : UInt16 #

Converts to UInt16. Truncates anything on the right side of the decimal point. Raises OverflowError in case of overflow.


[View source]
def to_u16! #

Converts to UInt16. Truncates anything on the right side of the decimal point, converting negative to positive. In case of overflow a wrapping is performed.


[View source]
def to_u32 : UInt32 #

Converts to UInt32. Truncates anything on the right side of the decimal point. Raises OverflowError in case of overflow.


[View source]
def to_u32! : UInt32 #

Converts to UInt32. Truncates anything on the right side of the decimal point, converting negative to positive. In case of overflow a wrapping is performed.


[View source]
def to_u64 : UInt64 #

Converts to UInt64. Truncates anything on the right side of the decimal point. Raises OverflowError in case of overflow.


[View source]
def to_u64! #

Converts to UInt64. Truncates anything on the right side of the decimal point, converting negative to positive. In case of overflow a wrapping is performed.


[View source]
def to_u8 : UInt8 #

Converts to UInt8. Truncates anything on the right side of the decimal point. Raises OverflowError in case of overflow.


[View source]
def to_u8! #

Converts to UInt8. Truncates anything on the right side of the decimal point, converting negative to positive. In case of overflow a wrapping is performed.


[View source]
def trunc : BigDecimal #

Rounds towards zero.


[View source]
def value : BigInt #

[View source]
def zero? : Bool #
Description copied from struct Number

Returns true if self is equal to zero.

0.zero? # => true
5.zero? # => false

[View source]