# Class: BigDecimal

Inherits:
Numeric
• Object
show all
Defined in:
bigdecimal.c,
lib/bigdecimal/util.rb,
bigdecimal.c

## Overview

BigDecimal provides arbitrary-precision floating point decimal arithmetic.

Copyright (C) 2002 by Shigeo Kobayashi <[email protected]>.

You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the README file of the BigDecimal distribution.

Documented by mathew <[email protected]>.

# Introduction

Ruby provides built-in support for arbitrary precision integer arithmetic.

For example:

42**13 #=> 1265437718438866624512

BigDecimal provides similar support for very large or very accurate floating point numbers.

Decimal arithmetic is also useful for general calculation, because it provides the correct answers people expect–whereas normal binary floating point arithmetic often introduces subtle errors because of the conversion between base 10 and base 2.

For example, try:

``````sum = 0
for i in (1..10000)
sum = sum + 0.0001
end
print sum #=> 0.9999999999999062
``````

and contrast with the output from:

``````require 'bigdecimal'

sum = BigDecimal.new("0")
for i in (1..10000)
sum = sum + BigDecimal.new("0.0001")
end
print sum #=> 0.1E1
``````

Similarly:

(BigDecimal.new(“1.2”) - BigDecimal(“1.0”)) == BigDecimal(“0.2”) #=> true

(1.2 - 1.0) == 0.2 #=> false

# Special features of accurate decimal arithmetic

Because BigDecimal is more accurate than normal binary floating point arithmetic, it requires some special values.

## Infinity

BigDecimal sometimes needs to return infinity, for example if you divide a value by zero.

BigDecimal.new(“1.0”) / BigDecimal.new(“0.0”) #=> infinity BigDecimal.new(“-1.0”) / BigDecimal.new(“0.0”) #=> -infinity

You can represent infinite numbers to BigDecimal using the strings `'Infinity'`, `'+Infinity'` and `'-Infinity'` (case-sensitive)

## Not a Number

When a computation results in an undefined value, the special value `NaN` (for 'not a number') is returned.

Example:

BigDecimal.new(“0.0”) / BigDecimal.new(“0.0”) #=> NaN

You can also create undefined values.

NaN is never considered to be the same as any other value, even NaN itself:

n = BigDecimal.new('NaN') n == 0.0 #=> nil n == n #=> nil

## Positive and negative zero

If a computation results in a value which is too small to be represented as a BigDecimal within the currently specified limits of precision, zero must be returned.

If the value which is too small to be represented is negative, a BigDecimal value of negative zero is returned.

BigDecimal.new(“1.0”) / BigDecimal.new(“-Infinity”) #=> -0.0

If the value is positive, a value of positive zero is returned.

BigDecimal.new(“1.0”) / BigDecimal.new(“Infinity”) #=> 0.0

(See BigDecimal.mode for how to specify limits of precision.)

Note that `-0.0` and `0.0` are considered to be the same for the purposes of comparison.

Note also that in mathematics, there is no particular concept of negative or positive zero; true mathematical zero has no sign.

## Constant Summary collapse

BASE =

Base value used in internal calculations. On a 32 bit system, BASE is 10000, indicating that calculation is done in groups of 4 digits. (If it were larger, BASE**2 wouldn't fit in 32 bits, so you couldn't guarantee that two groups could always be multiplied together without overflow.)

`INT2FIX((SIGNED_VALUE)VpBaseVal())`
EXCEPTION_ALL =

Determines whether overflow, underflow or zero divide result in an exception being thrown. See BigDecimal.mode.

`0xff`
EXCEPTION_NaN =

Determines what happens when the result of a computation is not a number (NaN). See BigDecimal.mode.

`0x02`
EXCEPTION_INFINITY =

Determines what happens when the result of a computation is infinity. See BigDecimal.mode.

`0x01`
EXCEPTION_UNDERFLOW =

Determines what happens when the result of a computation is an underflow (a result too small to be represented). See BigDecimal.mode.

`0x04`
EXCEPTION_OVERFLOW =

Determines what happens when the result of a computation is an overflow (a result too large to be represented). See BigDecimal.mode.

`0x01`
EXCEPTION_ZERODIVIDE =

Determines what happens when a division by zero is performed. See BigDecimal.mode.

`0x01`
ROUND_MODE =

Determines what happens when a result must be rounded in order to fit in the appropriate number of significant digits. See BigDecimal.mode.

`0x100`
ROUND_UP =

Indicates that values should be rounded away from zero. See BigDecimal.mode.

`1`
ROUND_DOWN =

Indicates that values should be rounded towards zero. See BigDecimal.mode.

`2`
ROUND_HALF_UP =

Indicates that digits >= 5 should be rounded up, others rounded down. See BigDecimal.mode.

`3`
ROUND_HALF_DOWN =

Indicates that digits >= 6 should be rounded up, others rounded down. See BigDecimal.mode.

`4`
ROUND_CEILING =

Round towards +infinity. See BigDecimal.mode.

`5`
ROUND_FLOOR =

Round towards -infinity. See BigDecimal.mode.

`6`
ROUND_HALF_EVEN =

Round towards the even neighbor. See BigDecimal.mode.

`7`
SIGN_NaN =

Indicates that a value is not a number. See BigDecimal.sign.

`0`
SIGN_POSITIVE_ZERO =

Indicates that a value is +0. See BigDecimal.sign.

`1`
SIGN_NEGATIVE_ZERO =

Indicates that a value is -0. See BigDecimal.sign.

`-1`
SIGN_POSITIVE_FINITE =

Indicates that a value is positive and finite. See BigDecimal.sign.

`2`
SIGN_NEGATIVE_FINITE =

Indicates that a value is negative and finite. See BigDecimal.sign.

`-2`
SIGN_POSITIVE_INFINITE =

Indicates that a value is positive and infinite. See BigDecimal.sign.

`3`
SIGN_NEGATIVE_INFINITE =

Indicates that a value is negative and infinite. See BigDecimal.sign.

`-3`
INFINITY =

Positive infinity value.

`BigDecimal_global_new(1, &arg, rb_cBigDecimal)`
NAN =

'Not a Number' value.

`BigDecimal_global_new(1, &arg, rb_cBigDecimal)`

## Class Method Summary collapse

• Internal method used to provide marshalling support.

• BigDecimal.double_fig.

• BigDecimal.limit(digits).

• BigDecimal.mode(mode, value).

• Excecute the provided block, but preserve the exception mode.

• Excecute the provided block, but preserve the precision limit.

• Excecute the provided block, but preserve the rounding mode.

• Returns the BigDecimal version number.

## Instance Method Summary collapse

• %: a%b = a - (a.to_f/b).floor * b.

• call-seq: mult(value, digits).

• It is a synonym of BigDecimal#power(exp).

• call-seq: add(value, digits).

• Return self.

• sub(value, digits).

• Return the negation of self.

• For c = self/r: with round operation.

• a < b.

• a <= b.

• The comparison operator.

• Tests for value equality; returns true if the values are equal.

• Tests for value equality; returns true if the values are equal.

• a > b.

• a >= b.

• Method used to provide marshalling support.

• Returns the absolute value.

• call-seq: add(value, digits).

• ceil(n).

• The coerce method provides support for Ruby type coercion.

• See BigDecimal#quo.

• Divides by the specified value, and returns the quotient and modulus as BigDecimal numbers.

• Tests for value equality; returns true if the values are equal.

• Returns the exponent of the BigDecimal number, as an Integer.

• Returns True if the value is finite (not NaN or infinite).

• Return the integer part of the number.

• floor(n).

• Return the fractional part of the number.

• Creates a hash for this BigDecimal.

• Returns nil, -1, or 1 depending on whether the value is finite, -infinity, or infinity.

• constructor

Create a new BigDecimal object.

• :nodoc:.

• Returns debugging information about the value as a string of comma-separated values in angle brackets with a leading #:.

• %: a%b = a - (a.to_f/b).floor * b.

• call-seq: mult(value, digits).

• Returns True if the value is Not a Number.

• Returns self if the value is non-zero, nil otherwise.

• power(n) power(n, prec).

• precs.

• For c = self/r: with round operation.

• remainder.

• round(n, mode).

• Returns the sign of the value.

• Splits a BigDecimal number into four parts, returned as an array of values.

• sqrt(n).

• call-seq: a.to_d -> bigdecimal.

• call-seq: a.to_digits -> string.

• Returns a new Float object having approximately the same value as the BigDecimal number.

• Returns the value as an integer (Fixnum or Bignum).

• Returns the value as an integer (Fixnum or Bignum).

• Converts a BigDecimal to a Rational.

• to_s(s).

• truncate(n).

• Returns True if the value is zero.

## Constructor Details

### #new(initial, digits) ⇒ Object

Create a new BigDecimal object.

initial

The initial value, as an Integer, a Float, a Rational, a BigDecimal, or a String.

If it is a String, spaces are ignored and unrecognized characters terminate the value.

digits

The number of significant digits, as a Fixnum. If omitted or 0, the number of significant digits is determined from the initial value.

The actual number of significant digits used in computation is usually larger than the specified number.

 ``` 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404``` ```# File 'bigdecimal.c', line 2388 static VALUE BigDecimal_initialize(int argc, VALUE *argv, VALUE self) { Real *pv = rb_check_typeddata(self, &BigDecimal_data_type); Real *x = BigDecimal_new(argc, argv); if (ToValue(x)) { pv = VpCopy(pv, x); } else { VpFree(pv); pv = x; } DATA_PTR(self) = pv; pv->obj = self; return self; }```

## Class Method Details

### ._load ⇒ Object

Internal method used to provide marshalling support. See the Marshal module.

 ``` 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394``` ```# File 'bigdecimal.c', line 371 static VALUE BigDecimal_load(VALUE self, VALUE str) { ENTER(2); Real *pv; unsigned char *pch; unsigned char ch; unsigned long m=0; SafeStringValue(str); pch = (unsigned char *)RSTRING_PTR(str); /* First get max prec */ while((*pch)!=(unsigned char)'\0' && (ch=*pch++)!=(unsigned char)':') { if(!ISDIGIT(ch)) { rb_raise(rb_eTypeError, "load failed: invalid character in the marshaled string"); } m = m*10 + (unsigned long)(ch-'0'); } if(m>VpBaseFig()) m -= VpBaseFig(); GUARD_OBJ(pv,VpNewRbClass(m,(char *)pch,self)); m /= VpBaseFig(); if(m && pv->MaxPrec>m) pv->MaxPrec = m+1; return ToValue(pv); }```

### .double_fig ⇒ Object

BigDecimal.double_fig

The BigDecimal.double_fig class method returns the number of digits a Float number is allowed to have. The result depends upon the CPU and OS in use.

 ``` 284 285 286 287 288``` ```# File 'bigdecimal.c', line 284 static VALUE BigDecimal_double_fig(VALUE self) { return INT2FIX(VpDblFig()); }```

### .limit ⇒ Object

BigDecimal.limit(digits)

Limit the number of significant digits in newly created BigDecimal numbers to the specified value. Rounding is performed as necessary, as specified by BigDecimal.mode.

A limit of 0, the default, means no upper limit.

The limit specified by this method takes less priority over any limit specified to instance methods such as ceil, floor, truncate, or round.

 ``` 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506``` ```# File 'bigdecimal.c', line 2489 static VALUE BigDecimal_limit(int argc, VALUE *argv, VALUE self) { VALUE nFig; VALUE nCur = INT2NUM(VpGetPrecLimit()); if(rb_scan_args(argc,argv,"01",&nFig)==1) { int nf; if(nFig==Qnil) return nCur; Check_Type(nFig, T_FIXNUM); nf = FIX2INT(nFig); if(nf<0) { rb_raise(rb_eArgError, "argument must be positive"); } VpSetPrecLimit(nf); } return nCur; }```

### .mode ⇒ Object

BigDecimal.mode(mode, value)

Controls handling of arithmetic exceptions and rounding. If no value is supplied, the current value is returned.

Six values of the mode parameter control the handling of arithmetic exceptions:

BigDecimal::EXCEPTION_NaN BigDecimal::EXCEPTION_INFINITY BigDecimal::EXCEPTION_UNDERFLOW BigDecimal::EXCEPTION_OVERFLOW BigDecimal::EXCEPTION_ZERODIVIDE BigDecimal::EXCEPTION_ALL

For each mode parameter above, if the value set is false, computation continues after an arithmetic exception of the appropriate type. When computation continues, results are as follows:

EXCEPTION_NaN

NaN

EXCEPTION_INFINITY

+infinity or -infinity

EXCEPTION_UNDERFLOW

0

EXCEPTION_OVERFLOW

+infinity or -infinity

EXCEPTION_ZERODIVIDE

+infinity or -infinity

One value of the mode parameter controls the rounding of numeric values: BigDecimal::ROUND_MODE. The values it can take are:

ROUND_UP, :up

round away from zero

ROUND_DOWN, :down, :truncate

round towards zero (truncate)

ROUND_HALF_UP, :half_up, :default

round towards the nearest neighbor, unless both neighbors are equidistant, in which case round away from zero. (default)

ROUND_HALF_DOWN, :half_down

round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards zero.

ROUND_HALF_EVEN, :half_even, :banker

round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards the even neighbor (Banker's rounding)

ROUND_CEILING, :ceiling, :ceil

round towards positive infinity (ceil)

ROUND_FLOOR, :floor

round towards negative infinity (floor)

 ``` 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523``` ```# File 'bigdecimal.c', line 470 static VALUE BigDecimal_mode(int argc, VALUE *argv, VALUE self) { VALUE which; VALUE val; unsigned long f,fo; if(rb_scan_args(argc,argv,"11",&which,&val)==1) val = Qnil; Check_Type(which, T_FIXNUM); f = (unsigned long)FIX2INT(which); if(f&VP_EXCEPTION_ALL) { /* Exception mode setting */ fo = VpGetException(); if(val==Qnil) return INT2FIX(fo); if(val!=Qfalse && val!=Qtrue) { rb_raise(rb_eArgError, "second argument must be true or false"); return Qnil; /* Not reached */ } if(f&VP_EXCEPTION_INFINITY) { VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_INFINITY): (fo&(~VP_EXCEPTION_INFINITY)))); } fo = VpGetException(); if(f&VP_EXCEPTION_NaN) { VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_NaN): (fo&(~VP_EXCEPTION_NaN)))); } fo = VpGetException(); if(f&VP_EXCEPTION_UNDERFLOW) { VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_UNDERFLOW): (fo&(~VP_EXCEPTION_UNDERFLOW)))); } fo = VpGetException(); if(f&VP_EXCEPTION_ZERODIVIDE) { VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_ZERODIVIDE): (fo&(~VP_EXCEPTION_ZERODIVIDE)))); } fo = VpGetException(); return INT2FIX(fo); } if (VP_ROUND_MODE == f) { /* Rounding mode setting */ unsigned short sw; fo = VpGetRoundMode(); if (NIL_P(val)) return INT2FIX(fo); sw = check_rounding_mode(val); fo = VpSetRoundMode(sw); return INT2FIX(fo); } rb_raise(rb_eTypeError, "first argument for BigDecimal#mode invalid"); return Qnil; }```

### .save_exception_mode { ... } ⇒ Object

Excecute the provided block, but preserve the exception mode

``````BigDecimal.save_exception_mode do
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)

BigDecimal.new(BigDecimal('Infinity'))
BigDecimal.new(BigDecimal('-Infinity'))
BigDecimal(BigDecimal.new('NaN'))
end
``````

For use with the BigDecimal::EXCEPTION_*

See BigDecimal.mode

Yields:

 ``` 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558``` ```# File 'bigdecimal.c', line 2549 static VALUE BigDecimal_save_exception_mode(VALUE self) { unsigned short const exception_mode = VpGetException(); int state; VALUE ret = rb_protect(rb_yield, Qnil, &state); VpSetException(exception_mode); if (state) rb_jump_tag(state); return ret; }```

### .save_limit { ... } ⇒ Object

Excecute the provided block, but preserve the precision limit

``````BigDecimal.limit(100)
puts BigDecimal.limit
BigDecimal.save_limit do
BigDecimal.limit(200)
puts BigDecimal.limit
end
puts BigDecimal.limit
``````

Yields:

 ``` 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608``` ```# File 'bigdecimal.c', line 2599 static VALUE BigDecimal_save_limit(VALUE self) { size_t const limit = VpGetPrecLimit(); int state; VALUE ret = rb_protect(rb_yield, Qnil, &state); VpSetPrecLimit(limit); if (state) rb_jump_tag(state); return ret; }```

### .save_rounding_mode { ... } ⇒ Object

Excecute the provided block, but preserve the rounding mode

``````BigDecimal.save_exception_mode do
BigDecimal.mode(BigDecimal::ROUND_MODE, :up)
puts BigDecimal.mode(BigDecimal::ROUND_MODE)
end
``````

For use with the BigDecimal::ROUND_*

See BigDecimal.mode

Yields:

 ``` 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583``` ```# File 'bigdecimal.c', line 2574 static VALUE BigDecimal_save_rounding_mode(VALUE self) { unsigned short const round_mode = VpGetRoundMode(); int state; VALUE ret = rb_protect(rb_yield, Qnil, &state); VpSetRoundMode(round_mode); if (state) rb_jump_tag(state); return ret; }```

### .ver ⇒ Object

Returns the BigDecimal version number.

 ``` 113 114 115 116 117 118 119 120 121 122``` ```# File 'bigdecimal.c', line 113 static VALUE BigDecimal_version(VALUE self) { /* * 1.0.0: Ruby 1.8.0 * 1.0.1: Ruby 1.8.1 * 1.1.0: Ruby 1.9.3 */ return rb_str_new2("1.1.0"); }```

## Instance Method Details

### #% ⇒ Object

%: a%b = a - (a.to_f/b).floor * b

 ``` 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351``` ```# File 'bigdecimal.c', line 1340 static VALUE BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */ { ENTER(3); Real *div=NULL, *mod=NULL; if(BigDecimal_DoDivmod(self,r,&div,&mod)) { SAVE(div); SAVE(mod); return ToValue(mod); } return DoSomeOne(self,r,'%'); }```

### #* ⇒ Object

call-seq: mult(value, digits)

Multiply by the specified value.

e.g.

``````c = a.mult(b,n)
c = a * b
``````
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to BigDecimal.mode.

 ``` 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175``` ```# File 'bigdecimal.c', line 1150 static VALUE BigDecimal_mult(VALUE self, VALUE r) { ENTER(5); Real *c, *a, *b; size_t mx; GUARD_OBJ(a,GetVpValue(self,1)); if (RB_TYPE_P(r, T_FLOAT)) { b = GetVpValueWithPrec(r, DBL_DIG+1, 1); } else if (RB_TYPE_P(r, T_RATIONAL)) { b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); } else { b = GetVpValue(r,0); } if(!b) return DoSomeOne(self,r,'*'); SAVE(b); mx = a->Prec + b->Prec; GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0")); VpMult(c, a, b); return ToValue(c); }```

### #**(exp) ⇒ Object

It is a synonym of BigDecimal#power(exp).

 ``` 2356 2357 2358 2359 2360``` ```# File 'bigdecimal.c', line 2356 static VALUE BigDecimal_power_op(VALUE self, VALUE exp) { return BigDecimal_power(1, &exp, self); }```

### #+ ⇒ Object

call-seq: add(value, digits)

Add the specified value.

e.g.

``````c = a.add(b,n)
c = a + b
``````
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to BigDecimal.mode.

 ``` 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874``` ```# File 'bigdecimal.c', line 835 static VALUE BigDecimal_add(VALUE self, VALUE r) { ENTER(5); Real *c, *a, *b; size_t mx; GUARD_OBJ(a, GetVpValue(self, 1)); if (RB_TYPE_P(r, T_FLOAT)) { b = GetVpValueWithPrec(r, DBL_DIG+1, 1); } else if (RB_TYPE_P(r, T_RATIONAL)) { b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); } else { b = GetVpValue(r,0); } if (!b) return DoSomeOne(self,r,'+'); SAVE(b); if (VpIsNaN(b)) return b->obj; if (VpIsNaN(a)) return a->obj; mx = GetAddSubPrec(a, b); if (mx == (size_t)-1L) { GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0")); VpAddSub(c, a, b, 1); } else { GUARD_OBJ(c, VpCreateRbObject(mx * (VpBaseFig() + 1), "0")); if(!mx) { VpSetInf(c, VpGetSign(a)); } else { VpAddSub(c, a, b, 1); } } return ToValue(c); }```

### #[email protected] ⇒ Object

Return self.

e.g.

``````b = +a  # b == a
``````
 ``` 812 813 814 815 816``` ```# File 'bigdecimal.c', line 812 static VALUE BigDecimal_uplus(VALUE self) { return self; }```

### #- ⇒ Object

sub(value, digits)

Subtract the specified value.

e.g.

``````c = a.sub(b,n)
c = a - b
``````
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to BigDecimal.mode.

 ``` 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926``` ```# File 'bigdecimal.c', line 889 static VALUE BigDecimal_sub(VALUE self, VALUE r) { ENTER(5); Real *c, *a, *b; size_t mx; GUARD_OBJ(a,GetVpValue(self,1)); if (RB_TYPE_P(r, T_FLOAT)) { b = GetVpValueWithPrec(r, DBL_DIG+1, 1); } else if (RB_TYPE_P(r, T_RATIONAL)) { b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); } else { b = GetVpValue(r,0); } if(!b) return DoSomeOne(self,r,'-'); SAVE(b); if(VpIsNaN(b)) return b->obj; if(VpIsNaN(a)) return a->obj; mx = GetAddSubPrec(a,b); if (mx == (size_t)-1L) { GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0")); VpAddSub(c, a, b, -1); } else { GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0")); if(!mx) { VpSetInf(c,VpGetSign(a)); } else { VpAddSub(c, a, b, -1); } } return ToValue(c); }```

### #[email protected] ⇒ Object

Return the negation of self.

e.g.

``````b = -a
b == a * -1
``````
 ``` 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133``` ```# File 'bigdecimal.c', line 1124 static VALUE BigDecimal_neg(VALUE self) { ENTER(5); Real *c, *a; GUARD_OBJ(a,GetVpValue(self,1)); GUARD_OBJ(c,VpCreateRbObject(a->Prec *(VpBaseFig() + 1), "0")); VpAsgn(c, a, -1); return ToValue(c); }```

### #/ ⇒ Object

For c = self/r: with round operation

 ``` 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246``` ```# File 'bigdecimal.c', line 1228 static VALUE BigDecimal_div(VALUE self, VALUE r) /* For c = self/r: with round operation */ { ENTER(5); Real *c=NULL, *res=NULL, *div = NULL; r = BigDecimal_divide(&c, &res, &div, self, r); if(r!=(VALUE)0) return r; /* coerced by other */ SAVE(c);SAVE(res);SAVE(div); /* a/b = c + r/b */ /* c xxxxx r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE */ /* Round */ if(VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */ VpInternalRound(c, 0, c->frac[c->Prec-1], (BDIGIT)(VpBaseVal()*(BDIGIT_DBL)res->frac[0]/div->frac[0])); } return ToValue(c); }```

### #< ⇒ Object

a < b

Returns true if a is less than b.

Values may be coerced to perform the comparison (see ==, BigDecimal#coerce).

 ``` 1070 1071 1072 1073 1074``` ```# File 'bigdecimal.c', line 1070 static VALUE BigDecimal_lt(VALUE self, VALUE r) { return BigDecimalCmp(self, r, '<'); }```

### #<= ⇒ Object

a <= b

Returns true if a is less than or equal to b.

Values may be coerced to perform the comparison (see ==, BigDecimal#coerce).

 ``` 1083 1084 1085 1086 1087``` ```# File 'bigdecimal.c', line 1083 static VALUE BigDecimal_le(VALUE self, VALUE r) { return BigDecimalCmp(self, r, 'L'); }```

### #<=> ⇒ Object

The comparison operator. a <=> b is 0 if a == b, 1 if a > b, -1 if a < b.

 ``` 1041 1042 1043 1044 1045``` ```# File 'bigdecimal.c', line 1041 static VALUE BigDecimal_comp(VALUE self, VALUE r) { return BigDecimalCmp(self, r, '*'); }```

### #== ⇒ Object

Tests for value equality; returns true if the values are equal.

The == and === operators and the eql? method have the same implementation for BigDecimal.

Values may be coerced to perform the comparison:

BigDecimal.new('1.0') == 1.0 -> true

 ``` 1057 1058 1059 1060 1061``` ```# File 'bigdecimal.c', line 1057 static VALUE BigDecimal_eq(VALUE self, VALUE r) { return BigDecimalCmp(self, r, '='); }```

### #=== ⇒ Object

Tests for value equality; returns true if the values are equal.

The == and === operators and the eql? method have the same implementation for BigDecimal.

Values may be coerced to perform the comparison:

BigDecimal.new('1.0') == 1.0 -> true

 ``` 1057 1058 1059 1060 1061``` ```# File 'bigdecimal.c', line 1057 static VALUE BigDecimal_eq(VALUE self, VALUE r) { return BigDecimalCmp(self, r, '='); }```

### #> ⇒ Object

a > b

Returns true if a is greater than b.

Values may be coerced to perform the comparison (see ==, BigDecimal#coerce).

 ``` 1096 1097 1098 1099 1100``` ```# File 'bigdecimal.c', line 1096 static VALUE BigDecimal_gt(VALUE self, VALUE r) { return BigDecimalCmp(self, r, '>'); }```

### #>= ⇒ Object

a >= b

Returns true if a is greater than or equal to b.

Values may be coerced to perform the comparison (see ==, BigDecimal#coerce)

 ``` 1109 1110 1111 1112 1113``` ```# File 'bigdecimal.c', line 1109 static VALUE BigDecimal_ge(VALUE self, VALUE r) { return BigDecimalCmp(self, r, 'G'); }```

### #_dump ⇒ Object

Method used to provide marshalling support.

``````inf = BigDecimal.new('Infinity')
=> #<BigDecimal:1e16fa8,'Infinity',9(9)>
BigDecimal._load(inf._dump)
=> #<BigDecimal:1df8dc8,'Infinity',9(9)>
``````

See the Marshal module.

 ``` 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366``` ```# File 'bigdecimal.c', line 349 static VALUE BigDecimal_dump(int argc, VALUE *argv, VALUE self) { ENTER(5); Real *vp; char *psz; VALUE dummy; volatile VALUE dump; rb_scan_args(argc, argv, "01", &dummy); GUARD_OBJ(vp,GetVpValue(self,1)); dump = rb_str_new(0,VpNumOfChars(vp,"E")+50); psz = RSTRING_PTR(dump); sprintf(psz, "%"PRIuSIZE":", VpMaxPrec(vp)*VpBaseFig()); VpToString(vp, psz+strlen(psz), 0, 0); rb_str_resize(dump, strlen(psz)); return dump; }```

### #abs ⇒ Object

Returns the absolute value.

BigDecimal('5').abs -> 5

BigDecimal('-3').abs -> 3

 ``` 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554``` ```# File 'bigdecimal.c', line 1541 static VALUE BigDecimal_abs(VALUE self) { ENTER(5); Real *c, *a; size_t mx; GUARD_OBJ(a,GetVpValue(self,1)); mx = a->Prec *(VpBaseFig() + 1); GUARD_OBJ(c,VpCreateRbObject(mx, "0")); VpAsgn(c, a, 1); VpChangeSign(c, 1); return ToValue(c); }```

### #add ⇒ Object

call-seq: add(value, digits)

Add the specified value.

e.g.

``````c = a.add(b,n)
c = a + b
``````
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to BigDecimal.mode.

 ``` 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499``` ```# File 'bigdecimal.c', line 1484 static VALUE BigDecimal_add2(VALUE self, VALUE b, VALUE n) { ENTER(2); Real *cv; SIGNED_VALUE mx = GetPositiveInt(n); if (mx == 0) return BigDecimal_add(self, b); else { size_t pl = VpSetPrecLimit(0); VALUE c = BigDecimal_add(self,b); VpSetPrecLimit(pl); GUARD_OBJ(cv,GetVpValue(c,1)); VpLeftRound(cv,VpGetRoundMode(),mx); return ToValue(cv); } }```

### #ceil ⇒ Object

ceil(n)

Return the smallest integer greater than or equal to the value, as a BigDecimal.

BigDecimal('3.14159').ceil #=> 4 BigDecimal('-9.1').ceil #=> -9

If n is specified and positive, the fractional part of the result has no more than that many digits.

If n is specified and negative, at least that many digits to the left of the decimal point will be 0 in the result.

BigDecimal('3.14159').ceil(3) #=> 3.142 BigDecimal('13345.234').ceil(-2) #=> 13400.0

 ``` 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804``` ```# File 'bigdecimal.c', line 1779 static VALUE BigDecimal_ceil(int argc, VALUE *argv, VALUE self) { ENTER(5); Real *c, *a; int iLoc; VALUE vLoc; size_t mx, pl = VpSetPrecLimit(0); if(rb_scan_args(argc,argv,"01",&vLoc)==0) { iLoc = 0; } else { Check_Type(vLoc, T_FIXNUM); iLoc = FIX2INT(vLoc); } GUARD_OBJ(a,GetVpValue(self,1)); mx = a->Prec *(VpBaseFig() + 1); GUARD_OBJ(c,VpCreateRbObject(mx, "0")); VpSetPrecLimit(pl); VpActiveRound(c,a,VP_ROUND_CEIL,iLoc); if (argc == 0) { return BigDecimal_to_i(ToValue(c)); } return ToValue(c); }```

### #coerce ⇒ Object

The coerce method provides support for Ruby type coercion. It is not enabled by default.

This means that binary operations like + * / or - can often be performed on a BigDecimal and an object of another type, if the other object can be coerced into a BigDecimal value.

e.g. a = BigDecimal.new(“1.0”) b = a / 2.0 -> 0.5

Note that coercing a String to a BigDecimal is not supported by default; it requires a special compile-time option when building Ruby.

 ``` 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802``` ```# File 'bigdecimal.c', line 780 static VALUE BigDecimal_coerce(VALUE self, VALUE other) { ENTER(2); VALUE obj; Real *b; if (RB_TYPE_P(other, T_FLOAT)) { obj = rb_assoc_new(other, BigDecimal_to_f(self)); } else { if (RB_TYPE_P(other, T_RATIONAL)) { Real* pv = DATA_PTR(self); GUARD_OBJ(b, GetVpValueWithPrec(other, pv->Prec*VpBaseFig(), 1)); } else { GUARD_OBJ(b, GetVpValue(other, 1)); } obj = rb_assoc_new(b->obj, self); } return obj; }```

### #div ⇒ Object

See BigDecimal#quo

 ``` 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482``` ```# File 'bigdecimal.c', line 1448 static VALUE BigDecimal_div2(int argc, VALUE *argv, VALUE self) { ENTER(5); VALUE b,n; int na = rb_scan_args(argc,argv,"11",&b,&n); if(na==1) { /* div in Float sense */ Real *div=NULL; Real *mod; if(BigDecimal_DoDivmod(self,b,&div,&mod)) { return BigDecimal_to_i(ToValue(div)); } return DoSomeOne(self,b,rb_intern("div")); } else { /* div in BigDecimal sense */ SIGNED_VALUE ix = GetPositiveInt(n); if (ix == 0) return BigDecimal_div(self, b); else { Real *res=NULL; Real *av=NULL, *bv=NULL, *cv=NULL; size_t mx = (ix+VpBaseFig()*2); size_t pl = VpSetPrecLimit(0); GUARD_OBJ(cv,VpCreateRbObject(mx,"0")); GUARD_OBJ(av,GetVpValue(self,1)); GUARD_OBJ(bv,GetVpValue(b,1)); mx = av->Prec + bv->Prec + 2; if(mx <= cv->MaxPrec) mx = cv->MaxPrec+1; GUARD_OBJ(res,VpCreateRbObject((mx * 2 + 2)*VpBaseFig(), "#0")); VpDivd(cv,res,av,bv); VpSetPrecLimit(pl); VpLeftRound(cv,VpGetRoundMode(),ix); return ToValue(cv); } } }```

### #divmod ⇒ Object

Divides by the specified value, and returns the quotient and modulus as BigDecimal numbers. The quotient is rounded towards negative infinity.

For example:

require 'bigdecimal'

a = BigDecimal.new(“42”) b = BigDecimal.new(“9”)

q,m = a.divmod(b)

c = q * b + m

a == c -> true

The quotient q is (a/b).floor, and the modulus is the amount that must be added to q * b to get a.

 ``` 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443``` ```# File 'bigdecimal.c', line 1432 static VALUE BigDecimal_divmod(VALUE self, VALUE r) { ENTER(5); Real *div=NULL, *mod=NULL; if(BigDecimal_DoDivmod(self,r,&div,&mod)) { SAVE(div); SAVE(mod); return rb_assoc_new(ToValue(div), ToValue(mod)); } return DoSomeOne(self,r,rb_intern("divmod")); }```

### #eql? ⇒ Boolean

Tests for value equality; returns true if the values are equal.

The == and === operators and the eql? method have the same implementation for BigDecimal.

Values may be coerced to perform the comparison:

BigDecimal.new('1.0') == 1.0 -> true

Returns:

• (Boolean)
 ``` 1057 1058 1059 1060 1061``` ```# File 'bigdecimal.c', line 1057 static VALUE BigDecimal_eq(VALUE self, VALUE r) { return BigDecimalCmp(self, r, '='); }```

### #exponent ⇒ Object

Returns the exponent of the BigDecimal number, as an Integer.

If the number can be represented as 0.xxxxxx*10**n where xxxxxx is a string of digits with no leading zeros, then n is the exponent.

 ``` 1967 1968 1969 1970 1971 1972``` ```# File 'bigdecimal.c', line 1967 static VALUE BigDecimal_exponent(VALUE self) { ssize_t e = VpExponent10(GetVpValue(self, 1)); return INT2NUM(e); }```

### #finite? ⇒ Boolean

Returns True if the value is finite (not NaN or infinite)

Returns:

• (Boolean)
 ``` 615 616 617 618 619 620 621 622``` ```# File 'bigdecimal.c', line 615 static VALUE BigDecimal_IsFinite(VALUE self) { Real *p = GetVpValue(self,1); if(VpIsNaN(p)) return Qfalse; if(VpIsInf(p)) return Qfalse; return Qtrue; }```

### #fix ⇒ Object

Return the integer part of the number.

 ``` 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594``` ```# File 'bigdecimal.c', line 1582 static VALUE BigDecimal_fix(VALUE self) { ENTER(5); Real *c, *a; size_t mx; GUARD_OBJ(a,GetVpValue(self,1)); mx = a->Prec *(VpBaseFig() + 1); GUARD_OBJ(c,VpCreateRbObject(mx, "0")); VpActiveRound(c,a,VP_ROUND_DOWN,0); /* 0: round off */ return ToValue(c); }```

### #floor ⇒ Object

floor(n)

Return the largest integer less than or equal to the value, as a BigDecimal.

BigDecimal('3.14159').floor #=> 3 BigDecimal('-9.1').floor #=> -10

If n is specified and positive, the fractional part of the result has no more than that many digits.

If n is specified and negative, at least that many digits to the left of the decimal point will be 0 in the result.

BigDecimal('3.14159').floor(3) #=> 3.141 BigDecimal('13345.234').floor(-2) #=> 13300.0

 ``` 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760``` ```# File 'bigdecimal.c', line 1732 static VALUE BigDecimal_floor(int argc, VALUE *argv, VALUE self) { ENTER(5); Real *c, *a; int iLoc; VALUE vLoc; size_t mx, pl = VpSetPrecLimit(0); if(rb_scan_args(argc,argv,"01",&vLoc)==0) { iLoc = 0; } else { Check_Type(vLoc, T_FIXNUM); iLoc = FIX2INT(vLoc); } GUARD_OBJ(a,GetVpValue(self,1)); mx = a->Prec *(VpBaseFig() + 1); GUARD_OBJ(c,VpCreateRbObject(mx, "0")); VpSetPrecLimit(pl); VpActiveRound(c,a,VP_ROUND_FLOOR,iLoc); #ifdef BIGDECIMAL_DEBUG VPrint(stderr, "floor: c=%\n", c); #endif if (argc == 0) { return BigDecimal_to_i(ToValue(c)); } return ToValue(c); }```

### #frac ⇒ Object

Return the fractional part of the number.

 ``` 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713``` ```# File 'bigdecimal.c', line 1701 static VALUE BigDecimal_frac(VALUE self) { ENTER(5); Real *c, *a; size_t mx; GUARD_OBJ(a,GetVpValue(self,1)); mx = a->Prec *(VpBaseFig() + 1); GUARD_OBJ(c,VpCreateRbObject(mx, "0")); VpFrac(c, a); return ToValue(c); }```

### #hash ⇒ Object

Creates a hash for this BigDecimal.

Two BigDecimals with equal sign, fractional part and exponent have the same hash.

 ``` 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335``` ```# File 'bigdecimal.c', line 320 static VALUE BigDecimal_hash(VALUE self) { ENTER(1); Real *p; st_index_t hash; GUARD_OBJ(p,GetVpValue(self,1)); hash = (st_index_t)p->sign; /* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */ if(hash == 2 || hash == (st_index_t)-2) { hash ^= rb_memhash(p->frac, sizeof(BDIGIT)*p->Prec); hash += p->exponent; } return INT2FIX(hash); }```

### #infinite? ⇒ Boolean

Returns nil, -1, or 1 depending on whether the value is finite, -infinity, or infinity.

Returns:

• (Boolean)
 ``` 605 606 607 608 609 610 611 612``` ```# File 'bigdecimal.c', line 605 static VALUE BigDecimal_IsInfinite(VALUE self) { Real *p = GetVpValue(self,1); if(VpIsPosInf(p)) return INT2FIX(1); if(VpIsNegInf(p)) return INT2FIX(-1); return Qnil; }```

### #initialize_copy ⇒ Object

:nodoc:

private method to dup and clone the provided BigDecimal `other`

 ``` 2410 2411 2412 2413 2414 2415 2416 2417 2418``` ```# File 'bigdecimal.c', line 2410 static VALUE BigDecimal_initialize_copy(VALUE self, VALUE other) { Real *pv = rb_check_typeddata(self, &BigDecimal_data_type); Real *x = rb_check_typeddata(other, &BigDecimal_data_type); DATA_PTR(self) = VpCopy(pv, x); return self; }```

### #inspect ⇒ Object

Returns debugging information about the value as a string of comma-separated values in angle brackets with a leading #:

BigDecimal.new(“1234.5678”).inspect -> “#<BigDecimal:b7ea1130,'0.12345678E4',8(12)>”

The first part is the address, the second is the value as a string, and the final part ss(mm) is the current number of significant digits and the maximum number of significant digits, respectively.

 ``` 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006``` ```# File 'bigdecimal.c', line 1984 static VALUE BigDecimal_inspect(VALUE self) { ENTER(5); Real *vp; volatile VALUE obj; size_t nc; char *psz, *tmp; GUARD_OBJ(vp,GetVpValue(self,1)); nc = VpNumOfChars(vp,"E"); nc +=(nc + 9) / 10; obj = rb_str_new(0, nc+256); psz = RSTRING_PTR(obj); sprintf(psz,"#", VpPrec(vp)*VpBaseFig(), VpMaxPrec(vp)*VpBaseFig()); rb_str_resize(obj, strlen(psz)); return obj; }```

### #modulo ⇒ Object

%: a%b = a - (a.to_f/b).floor * b

 ``` 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351``` ```# File 'bigdecimal.c', line 1340 static VALUE BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */ { ENTER(3); Real *div=NULL, *mod=NULL; if(BigDecimal_DoDivmod(self,r,&div,&mod)) { SAVE(div); SAVE(mod); return ToValue(mod); } return DoSomeOne(self,r,'%'); }```

### #mult ⇒ Object

call-seq: mult(value, digits)

Multiply by the specified value.

e.g.

``````c = a.mult(b,n)
c = a * b
``````
digits

If specified and less than the number of significant digits of the

result, the result is rounded to that number of digits, according to BigDecimal.mode.

 ``` 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533``` ```# File 'bigdecimal.c', line 1518 static VALUE BigDecimal_mult2(VALUE self, VALUE b, VALUE n) { ENTER(2); Real *cv; SIGNED_VALUE mx = GetPositiveInt(n); if (mx == 0) return BigDecimal_mult(self, b); else { size_t pl = VpSetPrecLimit(0); VALUE c = BigDecimal_mult(self,b); VpSetPrecLimit(pl); GUARD_OBJ(cv,GetVpValue(c,1)); VpLeftRound(cv,VpGetRoundMode(),mx); return ToValue(cv); } }```

### #nan? ⇒ Boolean

Returns True if the value is Not a Number

Returns:

• (Boolean)
 ``` 594 595 596 597 598 599 600``` ```# File 'bigdecimal.c', line 594 static VALUE BigDecimal_IsNaN(VALUE self) { Real *p = GetVpValue(self,1); if(VpIsNaN(p)) return Qtrue; return Qfalse; }```

### #nonzero? ⇒ Boolean

Returns self if the value is non-zero, nil otherwise.

Returns:

• (Boolean)
 ``` 1031 1032 1033 1034 1035 1036``` ```# File 'bigdecimal.c', line 1031 static VALUE BigDecimal_nonzero(VALUE self) { Real *a = GetVpValue(self,1); return VpIsZero(a) ? Qnil : self; }```

### #power ⇒ Object

power(n) power(n, prec)

Returns the value raised to the power of n.

Note that n must be an Integer.

Also available as the operator **

 ``` 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349``` ```# File 'bigdecimal.c', line 2130 static VALUE BigDecimal_power(int argc, VALUE*argv, VALUE self) { ENTER(5); VALUE vexp, prec; Real* exp = NULL; Real *x, *y; ssize_t mp, ma, n; SIGNED_VALUE int_exp; double d; rb_scan_args(argc, argv, "11", &vexp, &prec); GUARD_OBJ(x, GetVpValue(self, 1)); n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec); if (VpIsNaN(x)) { y = VpCreateRbObject(n, "0#"); RB_GC_GUARD(y->obj); VpSetNaN(y); return ToValue(y); } retry: switch (TYPE(vexp)) { case T_FIXNUM: break; case T_BIGNUM: break; case T_FLOAT: d = RFLOAT_VALUE(vexp); if (d == round(d)) { vexp = LL2NUM((LONG_LONG)round(d)); goto retry; } exp = GetVpValueWithPrec(vexp, DBL_DIG+1, 1); break; case T_RATIONAL: if (is_zero(RRATIONAL(vexp)->num)) { if (is_positive(vexp)) { vexp = INT2FIX(0); goto retry; } } else if (is_one(RRATIONAL(vexp)->den)) { vexp = RRATIONAL(vexp)->num; goto retry; } exp = GetVpValueWithPrec(vexp, n, 1); break; case T_DATA: if (is_kind_of_BigDecimal(vexp)) { VALUE zero = INT2FIX(0); VALUE rounded = BigDecimal_round(1, &zero, vexp); if (RTEST(BigDecimal_eq(vexp, rounded))) { vexp = BigDecimal_to_i(vexp); goto retry; } exp = DATA_PTR(vexp); break; } /* fall through */ default: rb_raise(rb_eTypeError, "wrong argument type %s (expected scalar Numeric)", rb_obj_classname(vexp)); } if (VpIsZero(x)) { if (is_negative(vexp)) { y = VpCreateRbObject(n, "#0"); RB_GC_GUARD(y->obj); if (VpGetSign(x) < 0) { if (is_integer(vexp)) { if (is_even(vexp)) { /* (-0) ** (-even_integer) -> Infinity */ VpSetPosInf(y); } else { /* (-0) ** (-odd_integer) -> -Infinity */ VpSetNegInf(y); } } else { /* (-0) ** (-non_integer) -> Infinity */ VpSetPosInf(y); } } else { /* (+0) ** (-num) -> Infinity */ VpSetPosInf(y); } return ToValue(y); } else if (is_zero(vexp)) { return ToValue(VpCreateRbObject(n, "1")); } else { return ToValue(VpCreateRbObject(n, "0")); } } if (is_zero(vexp)) { return ToValue(VpCreateRbObject(n, "1")); } else if (is_one(vexp)) { return self; } if (VpIsInf(x)) { if (is_negative(vexp)) { if (VpGetSign(x) < 0) { if (is_integer(vexp)) { if (is_even(vexp)) { /* (-Infinity) ** (-even_integer) -> +0 */ return ToValue(VpCreateRbObject(n, "0")); } else { /* (-Infinity) ** (-odd_integer) -> -0 */ return ToValue(VpCreateRbObject(n, "-0")); } } else { /* (-Infinity) ** (-non_integer) -> -0 */ return ToValue(VpCreateRbObject(n, "-0")); } } else { return ToValue(VpCreateRbObject(n, "0")); } } else { y = VpCreateRbObject(n, "0#"); if (VpGetSign(x) < 0) { if (is_integer(vexp)) { if (is_even(vexp)) { VpSetPosInf(y); } else { VpSetNegInf(y); } } else { /* TODO: support complex */ rb_raise(rb_eMathDomainError, "a non-integral exponent for a negative base"); } } else { VpSetPosInf(y); } return ToValue(y); } } if (exp != NULL) { return rmpd_power_by_big_decimal(x, exp, n); } else if (RB_TYPE_P(vexp, T_BIGNUM)) { VALUE abs_value = BigDecimal_abs(self); if (is_one(abs_value)) { return ToValue(VpCreateRbObject(n, "1")); } else if (RTEST(rb_funcall(abs_value, '<', 1, INT2FIX(1)))) { if (is_negative(vexp)) { y = VpCreateRbObject(n, "0#"); if (is_even(vexp)) { VpSetInf(y, VpGetSign(x)); } else { VpSetInf(y, -VpGetSign(x)); } return ToValue(y); } else if (VpGetSign(x) < 0 && is_even(vexp)) { return ToValue(VpCreateRbObject(n, "-0")); } else { return ToValue(VpCreateRbObject(n, "0")); } } else { if (is_positive(vexp)) { y = VpCreateRbObject(n, "0#"); if (is_even(vexp)) { VpSetInf(y, VpGetSign(x)); } else { VpSetInf(y, -VpGetSign(x)); } return ToValue(y); } else if (VpGetSign(x) < 0 && is_even(vexp)) { return ToValue(VpCreateRbObject(n, "-0")); } else { return ToValue(VpCreateRbObject(n, "0")); } } } int_exp = FIX2INT(vexp); ma = int_exp; if (ma < 0) ma = -ma; if (ma == 0) ma = 1; if (VpIsDef(x)) { mp = x->Prec * (VpBaseFig() + 1); GUARD_OBJ(y, VpCreateRbObject(mp * (ma + 1), "0")); } else { GUARD_OBJ(y, VpCreateRbObject(1, "0")); } VpPower(y, x, int_exp); return ToValue(y); }```

### #precs ⇒ Object

precs

Returns an Array of two Integer values.

The first value is the current number of significant digits in the BigDecimal. The second value is the maximum number of significant digits for the BigDecimal.

 ``` 299 300 301 302 303 304 305 306 307 308 309 310``` ```# File 'bigdecimal.c', line 299 static VALUE BigDecimal_prec(VALUE self) { ENTER(1); Real *p; VALUE obj; GUARD_OBJ(p,GetVpValue(self,1)); obj = rb_assoc_new(INT2NUM(p->Prec*VpBaseFig()), INT2NUM(p->MaxPrec*VpBaseFig())); return obj; }```

### #quo ⇒ Object

For c = self/r: with round operation

 ``` 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246``` ```# File 'bigdecimal.c', line 1228 static VALUE BigDecimal_div(VALUE self, VALUE r) /* For c = self/r: with round operation */ { ENTER(5); Real *c=NULL, *res=NULL, *div = NULL; r = BigDecimal_divide(&c, &res, &div, self, r); if(r!=(VALUE)0) return r; /* coerced by other */ SAVE(c);SAVE(res);SAVE(div); /* a/b = c + r/b */ /* c xxxxx r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE */ /* Round */ if(VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */ VpInternalRound(c, 0, c->frac[c->Prec-1], (BDIGIT)(VpBaseVal()*(BDIGIT_DBL)res->frac[0]/div->frac[0])); } return ToValue(c); }```

### #remainder ⇒ Object

remainder

 ``` 1403 1404 1405 1406 1407 1408 1409 1410 1411``` ```# File 'bigdecimal.c', line 1403 static VALUE BigDecimal_remainder(VALUE self, VALUE r) /* remainder */ { VALUE f; Real *d,*rv=0; f = BigDecimal_divremain(self,r,&d,&rv); if(f!=(VALUE)0) return f; return ToValue(rv); }```

### #round ⇒ Object

round(n, mode)

Round to the nearest 1 (by default), returning the result as a BigDecimal.

BigDecimal('3.14159').round #=> 3 BigDecimal('8.7').round #=> 9

If n is specified and positive, the fractional part of the result has no more than that many digits.

If n is specified and negative, at least that many digits to the left of the decimal point will be 0 in the result.

BigDecimal('3.14159').round(3) #=> 3.142 BigDecimal('13345.234').round(-2) #=> 13300.0

The value of the optional mode argument can be used to determine how rounding is performed; see BigDecimal.mode.

 ``` 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653``` ```# File 'bigdecimal.c', line 1616 static VALUE BigDecimal_round(int argc, VALUE *argv, VALUE self) { ENTER(5); Real *c, *a; int iLoc = 0; VALUE vLoc; VALUE vRound; size_t mx, pl; unsigned short sw = VpGetRoundMode(); switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) { case 0: iLoc = 0; break; case 1: Check_Type(vLoc, T_FIXNUM); iLoc = FIX2INT(vLoc); break; case 2: Check_Type(vLoc, T_FIXNUM); iLoc = FIX2INT(vLoc); sw = check_rounding_mode(vRound); break; } pl = VpSetPrecLimit(0); GUARD_OBJ(a,GetVpValue(self,1)); mx = a->Prec *(VpBaseFig() + 1); GUARD_OBJ(c,VpCreateRbObject(mx, "0")); VpSetPrecLimit(pl); VpActiveRound(c,a,sw,iLoc); if (argc == 0) { return BigDecimal_to_i(ToValue(c)); } return ToValue(c); }```

### #sign ⇒ Object

Returns the sign of the value.

Returns a positive value if > 0, a negative value if < 0, and a zero if == 0.

The specific value returned indicates the type and sign of the BigDecimal, as follows:

BigDecimal::SIGN_NaN

value is Not a Number

BigDecimal::SIGN_POSITIVE_ZERO

value is +0

BigDecimal::SIGN_NEGATIVE_ZERO

value is -0

BigDecimal::SIGN_POSITIVE_INFINITE

value is +infinity

BigDecimal::SIGN_NEGATIVE_INFINITE

value is -infinity

BigDecimal::SIGN_POSITIVE_FINITE

value is positive

BigDecimal::SIGN_NEGATIVE_FINITE

value is negative

 ``` 2524 2525 2526 2527 2528 2529``` ```# File 'bigdecimal.c', line 2524 static VALUE BigDecimal_sign(VALUE self) { /* sign */ int s = GetVpValue(self,1)->sign; return INT2FIX(s); }```

### #split ⇒ Object

Splits a BigDecimal number into four parts, returned as an array of values.

The first value represents the sign of the BigDecimal, and is -1 or 1, or 0 if the BigDecimal is Not a Number.

The second value is a string representing the significant digits of the BigDecimal, with no leading zeros.

The third value is the base used for arithmetic (currently always 10) as an Integer.

The fourth value is an Integer exponent.

If the BigDecimal can be represented as 0.xxxxxx*10**n, then xxxxxx is the string of significant digits with no leading zeros, and n is the exponent.

From these values, you can translate a BigDecimal to a float as follows:

``````sign, significant_digits, base, exponent = a.split
f = sign * "0.#{significant_digits}".to_f * (base ** exponent)
``````

(Note that the to_f method is provided as a more convenient way to translate a BigDecimal to a Float.)

 ``` 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960``` ```# File 'bigdecimal.c', line 1930 static VALUE BigDecimal_split(VALUE self) { ENTER(5); Real *vp; VALUE obj,str; ssize_t e, s; char *psz1; GUARD_OBJ(vp,GetVpValue(self,1)); str = rb_str_new(0, VpNumOfChars(vp,"E")); psz1 = RSTRING_PTR(str); VpSzMantissa(vp,psz1); s = 1; if(psz1[0]=='-') { size_t len = strlen(psz1+1); memmove(psz1, psz1+1, len); psz1[len] = '\0'; s = -1; } if(psz1[0]=='N') s=0; /* NaN */ e = VpExponent10(vp); obj = rb_ary_new2(4); rb_ary_push(obj, INT2FIX(s)); rb_ary_push(obj, str); rb_str_resize(str, strlen(psz1)); rb_ary_push(obj, INT2FIX(10)); rb_ary_push(obj, INT2NUM(e)); return obj; }```

### #sqrt ⇒ Object

sqrt(n)

Returns the square root of the value.

Result has at least n significant digits.

 ``` 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578``` ```# File 'bigdecimal.c', line 1563 static VALUE BigDecimal_sqrt(VALUE self, VALUE nFig) { ENTER(5); Real *c, *a; size_t mx, n; GUARD_OBJ(a,GetVpValue(self,1)); mx = a->Prec *(VpBaseFig() + 1); n = GetPositiveInt(nFig) + VpDblFig() + 1; if(mx <= n) mx = n; GUARD_OBJ(c,VpCreateRbObject(mx, "0")); VpSqrt(c, a); return ToValue(c); }```

### #sub ⇒ Object

 ``` 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516``` ```# File 'bigdecimal.c', line 1501 static VALUE BigDecimal_sub2(VALUE self, VALUE b, VALUE n) { ENTER(2); Real *cv; SIGNED_VALUE mx = GetPositiveInt(n); if (mx == 0) return BigDecimal_sub(self, b); else { size_t pl = VpSetPrecLimit(0); VALUE c = BigDecimal_sub(self,b); VpSetPrecLimit(pl); GUARD_OBJ(cv,GetVpValue(c,1)); VpLeftRound(cv,VpGetRoundMode(),mx); return ToValue(cv); } }```

### #to_d ⇒ Object

call-seq:

``````a.to_d -> bigdecimal
``````

Returns self.

 ``` 79 80 81``` ```# File 'lib/bigdecimal/util.rb', line 79 def to_d self end```

### #to_digits ⇒ Object

call-seq:

``````a.to_digits -> string
``````

Converts a BigDecimal to a String of the form “nnnnnn.mmm”. This method is deprecated; use BigDecimal#to_s(“F”) instead.

``````require 'bigdecimal'
require 'bigdecimal/util'

d = BigDecimal.new("3.14")
d.to_digits
# => "3.14"
``````
 ``` 65 66 67 68 69 70 71 72 73``` ```# File 'lib/bigdecimal/util.rb', line 65 def to_digits if self.nan? || self.infinite? || self.zero? self.to_s else i = self.to_i.to_s _,f,_,z = self.frac.split i + "." + ("0"*(-z)) + f end end```

### #to_f ⇒ Object

Returns a new Float object having approximately the same value as the BigDecimal number. Normal accuracy limits and built-in errors of binary Float arithmetic apply.

 ``` 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729``` ```# File 'bigdecimal.c', line 687 static VALUE BigDecimal_to_f(VALUE self) { ENTER(1); Real *p; double d; SIGNED_VALUE e; char *buf; volatile VALUE str; GUARD_OBJ(p, GetVpValue(self, 1)); if (VpVtoD(&d, &e, p) != 1) return rb_float_new(d); if (e > (SIGNED_VALUE)(DBL_MAX_10_EXP+BASE_FIG)) goto overflow; if (e < (SIGNED_VALUE)(DBL_MIN_10_EXP-BASE_FIG)) goto underflow; str = rb_str_new(0, VpNumOfChars(p,"E")); buf = RSTRING_PTR(str); VpToString(p, buf, 0, 0); errno = 0; d = strtod(buf, 0); if (errno == ERANGE) { if (d == 0.0) goto underflow; if (fabs(d) >= HUGE_VAL) goto overflow; } return rb_float_new(d); overflow: VpException(VP_EXCEPTION_OVERFLOW, "BigDecimal to Float conversion", 0); if (p->sign >= 0) return rb_float_new(VpGetDoublePosInf()); else return rb_float_new(VpGetDoubleNegInf()); underflow: VpException(VP_EXCEPTION_UNDERFLOW, "BigDecimal to Float conversion", 0); if (p->sign >= 0) return rb_float_new(0.0); else return rb_float_new(-0.0); }```

### #to_i ⇒ Object

Returns the value as an integer (Fixnum or Bignum).

If the BigNumber is infinity or NaN, raises FloatDomainError.

 ``` 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681``` ```# File 'bigdecimal.c', line 642 static VALUE BigDecimal_to_i(VALUE self) { ENTER(5); ssize_t e, nf; Real *p; GUARD_OBJ(p,GetVpValue(self,1)); BigDecimal_check_num(p); e = VpExponent10(p); if(e<=0) return INT2FIX(0); nf = VpBaseFig(); if(e<=nf) { return LONG2NUM((long)(VpGetSign(p)*(BDIGIT_DBL_SIGNED)p->frac[0])); } else { VALUE a = BigDecimal_split(self); VALUE digits = RARRAY_PTR(a)[1]; VALUE numerator = rb_funcall(digits, rb_intern("to_i"), 0); VALUE ret; ssize_t dpower = e - (ssize_t)RSTRING_LEN(digits); if (VpGetSign(p) < 0) { numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1)); } if (dpower < 0) { ret = rb_funcall(numerator, rb_intern("div"), 1, rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(-dpower))); } else ret = rb_funcall(numerator, '*', 1, rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(dpower))); if (RB_TYPE_P(ret, T_FLOAT)) rb_raise(rb_eFloatDomainError, "Infinity"); return ret; } }```

### #to_int ⇒ Object

Returns the value as an integer (Fixnum or Bignum).

If the BigNumber is infinity or NaN, raises FloatDomainError.

 ``` 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681``` ```# File 'bigdecimal.c', line 642 static VALUE BigDecimal_to_i(VALUE self) { ENTER(5); ssize_t e, nf; Real *p; GUARD_OBJ(p,GetVpValue(self,1)); BigDecimal_check_num(p); e = VpExponent10(p); if(e<=0) return INT2FIX(0); nf = VpBaseFig(); if(e<=nf) { return LONG2NUM((long)(VpGetSign(p)*(BDIGIT_DBL_SIGNED)p->frac[0])); } else { VALUE a = BigDecimal_split(self); VALUE digits = RARRAY_PTR(a)[1]; VALUE numerator = rb_funcall(digits, rb_intern("to_i"), 0); VALUE ret; ssize_t dpower = e - (ssize_t)RSTRING_LEN(digits); if (VpGetSign(p) < 0) { numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1)); } if (dpower < 0) { ret = rb_funcall(numerator, rb_intern("div"), 1, rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(-dpower))); } else ret = rb_funcall(numerator, '*', 1, rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(dpower))); if (RB_TYPE_P(ret, T_FLOAT)) rb_raise(rb_eFloatDomainError, "Infinity"); return ret; } }```

### #to_r ⇒ Object

Converts a BigDecimal to a Rational.

 ``` 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764``` ```# File 'bigdecimal.c', line 734 static VALUE BigDecimal_to_r(VALUE self) { Real *p; ssize_t sign, power, denomi_power; VALUE a, digits, numerator; p = GetVpValue(self,1); BigDecimal_check_num(p); sign = VpGetSign(p); power = VpExponent10(p); a = BigDecimal_split(self); digits = RARRAY_PTR(a)[1]; denomi_power = power - RSTRING_LEN(digits); numerator = rb_funcall(digits, rb_intern("to_i"), 0); if (sign < 0) { numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1)); } if (denomi_power < 0) { return rb_Rational(numerator, rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(-denomi_power))); } else { return rb_Rational1(rb_funcall(numerator, '*', 1, rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(denomi_power)))); } }```

### #to_s ⇒ Object

to_s(s)

Converts the value to a string.

The default format looks like 0.xxxxEnn.

The optional parameter s consists of either an integer; or an optional '+' or ' ', followed by an optional number, followed by an optional 'E' or 'F'.

If there is a '+' at the start of s, positive values are returned with a leading '+'.

A space at the start of s returns positive values with a leading space.

If s contains a number, a space is inserted after each group of that many fractional digits.

If s ends with an 'E', engineering notation (0.xxxxEnn) is used.

If s ends with an 'F', conventional floating point notation is used.

Examples:

BigDecimal.new('-123.45678901234567890').to_s('5F')

``````#=> '-123.45678 90123 45678 9'
``````

BigDecimal.new('123.45678901234567890').to_s('+8F')

``````#=> '+123.45678901 23456789'
``````

BigDecimal.new('123.45678901234567890').to_s(' F')

``````#=> ' 123.4567890123456789'
``````
 ``` 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904``` ```# File 'bigdecimal.c', line 1839 static VALUE BigDecimal_to_s(int argc, VALUE *argv, VALUE self) { ENTER(5); int fmt = 0; /* 0:E format */ int fPlus = 0; /* =0:default,=1: set ' ' before digits ,set '+' before digits. */ Real *vp; volatile VALUE str; char *psz; char ch; size_t nc, mc = 0; VALUE f; GUARD_OBJ(vp,GetVpValue(self,1)); if (rb_scan_args(argc,argv,"01",&f)==1) { if (RB_TYPE_P(f, T_STRING)) { SafeStringValue(f); psz = RSTRING_PTR(f); if (*psz == ' ') { fPlus = 1; psz++; } else if (*psz == '+') { fPlus = 2; psz++; } while ((ch = *psz++) != 0) { if (ISSPACE(ch)) { continue; } if (!ISDIGIT(ch)) { if (ch == 'F' || ch == 'f') { fmt = 1; /* F format */ } break; } mc = mc * 10 + ch - '0'; } } else { mc = (size_t)GetPositiveInt(f); } } if (fmt) { nc = VpNumOfChars(vp, "F"); } else { nc = VpNumOfChars(vp, "E"); } if (mc > 0) { nc += (nc + mc - 1) / mc + 1; } str = rb_str_new(0, nc); psz = RSTRING_PTR(str); if (fmt) { VpToFString(vp, psz, mc, fPlus); } else { VpToString (vp, psz, mc, fPlus); } rb_str_resize(str, strlen(psz)); return str; }```

### #truncate ⇒ Object

truncate(n)

Truncate to the nearest 1, returning the result as a BigDecimal.

BigDecimal('3.14159').truncate #=> 3 BigDecimal('8.7').truncate #=> 8

If n is specified and positive, the fractional part of the result has no more than that many digits.

If n is specified and negative, at least that many digits to the left of the decimal point will be 0 in the result.

BigDecimal('3.14159').truncate(3) #=> 3.141 BigDecimal('13345.234').truncate(-2) #=> 13300.0

 ``` 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697``` ```# File 'bigdecimal.c', line 1672 static VALUE BigDecimal_truncate(int argc, VALUE *argv, VALUE self) { ENTER(5); Real *c, *a; int iLoc; VALUE vLoc; size_t mx, pl = VpSetPrecLimit(0); if(rb_scan_args(argc,argv,"01",&vLoc)==0) { iLoc = 0; } else { Check_Type(vLoc, T_FIXNUM); iLoc = FIX2INT(vLoc); } GUARD_OBJ(a,GetVpValue(self,1)); mx = a->Prec *(VpBaseFig() + 1); GUARD_OBJ(c,VpCreateRbObject(mx, "0")); VpSetPrecLimit(pl); VpActiveRound(c,a,VP_ROUND_DOWN,iLoc); /* 0: truncate */ if (argc == 0) { return BigDecimal_to_i(ToValue(c)); } return ToValue(c); }```

### #zero? ⇒ Boolean

Returns True if the value is zero.

Returns:

• (Boolean)
 ``` 1023 1024 1025 1026 1027 1028``` ```# File 'bigdecimal.c', line 1023 static VALUE BigDecimal_zero(VALUE self) { Real *a = GetVpValue(self,1); return VpIsZero(a) ? Qtrue : Qfalse; }```