summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/bigdecimal/bigdecimal.c46
-rw-r--r--ext/bigdecimal/bigdecimal.h4
-rw-r--r--ext/bigdecimal/bigdecimal_en.html48
-rw-r--r--ext/bigdecimal/bigdecimal_ja.html59
4 files changed, 86 insertions, 71 deletions
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index a5d29660fb..a1253e92e7 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -919,12 +919,15 @@ static VALUE
BigDecimal_round(int argc, VALUE *argv, VALUE self)
{
ENTER(5);
- Real *c, *a;
- int iLoc;
- int sw;
+ Real *c, *a;
+ int iLoc;
U_LONG mx;
- VALUE vLoc;
- int na = rb_scan_args(argc,argv,"01",&vLoc);
+ VALUE vLoc;
+ VALUE vRound;
+
+ int sw = VpGetRoundMode();
+
+ int na = rb_scan_args(argc,argv,"02",&vLoc,&vRound);
switch(na) {
case 0:
iLoc = 0;
@@ -933,12 +936,18 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
Check_Type(vLoc, T_FIXNUM);
iLoc = FIX2INT(vLoc);
break;
+ case 2:
+ Check_Type(vLoc, T_FIXNUM);
+ iLoc = FIX2INT(vLoc);
+ Check_Type(vRound, T_FIXNUM);
+ sw = VpSetRoundMode(FIX2INT(vRound));
+ break;
}
GUARD_OBJ(a,GetVpValue(self,1));
mx = a->Prec *(VpBaseFig() + 1);
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
- VpActiveRound(c,a,VpGetRoundMode(),iLoc);
+ VpActiveRound(c,a,sw,iLoc);
return ToValue(c);
}
@@ -1291,7 +1300,7 @@ Init_bigdecimal(void)
rb_define_const(rb_cBigDecimal, "ROUND_HALF_DOWN",INT2FIX(VP_ROUND_HALF_DOWN));
rb_define_const(rb_cBigDecimal, "ROUND_CEILING",INT2FIX(VP_ROUND_CEIL));
rb_define_const(rb_cBigDecimal, "ROUND_FLOOR",INT2FIX(VP_ROUND_FLOOR));
- rb_define_const(rb_cBigDecimal, "ROUND_EVEN",INT2FIX(VP_ROUND_EVEN));
+ rb_define_const(rb_cBigDecimal, "ROUND_HALF_EVEN",INT2FIX(VP_ROUND_HALF_EVEN));
/* Constants for sign value */
rb_define_const(rb_cBigDecimal, "SIGN_NaN",INT2FIX(VP_SIGN_NaN));
@@ -1484,13 +1493,12 @@ VpGetRoundMode(void)
VP_EXPORT unsigned long
VpSetRoundMode(unsigned long n)
{
- unsigned long s = gfRoundMode;
- if(n!=VP_ROUND_UP && n!=VP_ROUND_DOWN &&
- n!=VP_ROUND_HALF_UP && n!=VP_ROUND_HALF_DOWN &&
- n!=VP_ROUND_CEIL && n!=VP_ROUND_FLOOR &&
- n!=VP_ROUND_EVEN) return s;
- gfRoundMode = n;
- return s;
+ if(n==VP_ROUND_UP || n!=VP_ROUND_DOWN ||
+ n==VP_ROUND_HALF_UP || n!=VP_ROUND_HALF_DOWN ||
+ n==VP_ROUND_CEIL || n!=VP_ROUND_FLOOR ||
+ n==VP_ROUND_HALF_EVEN
+ ) gfRoundMode = n;
+ return gfRoundMode;
}
/*
@@ -3212,7 +3220,7 @@ VpCtoV(Real *a, char *int_chr, U_LONG ni, char *frac, U_LONG nf, char *exp_chr,
++me;
}
while(i < me) {
- es = e*BASE_FIG;
+ es = e*((S_INT)BASE_FIG);
e = e * 10 + exp_chr[i] - '0';
if(es>e*((S_INT)BASE_FIG)) {
return VpException(VP_EXCEPTION_INFINITY,"Exponent overflow",0);
@@ -3247,8 +3255,8 @@ VpCtoV(Real *a, char *int_chr, U_LONG ni, char *frac, U_LONG nf, char *exp_chr,
while(ef) {
if(e>=0) eb = e;
else eb = -e;
- ef = eb / BASE_FIG;
- ef = eb - ef * BASE_FIG;
+ ef = eb / ((S_INT)BASE_FIG);
+ ef = eb - ef * ((S_INT)BASE_FIG);
if(ef) {
++j; /* Means to add one more preceeding zero */
++e;
@@ -3669,7 +3677,7 @@ VpMidRound(Real *y, int f, int nf)
case VP_ROUND_FLOOR: /* floor */
if(v && (VpGetSign(y)<0)) ++div;
break;
- case VP_ROUND_EVEN: /* Banker's rounding */
+ case VP_ROUND_HALF_EVEN: /* Banker's rounding */
if(v>5) ++div;
else if(v==5) {
if(i==(BASE_FIG-1)) {
@@ -3751,7 +3759,7 @@ VpInternalRound(Real *c,int ixDigit,U_LONG vPrev,U_LONG v)
case VP_ROUND_FLOOR: /* floor */
if(v && (VpGetSign(c)<0)) f = 1;
break;
- case VP_ROUND_EVEN: /* Banker's rounding */
+ case VP_ROUND_HALF_EVEN: /* Banker's rounding */
if(v>5) f = 1;
else if(v==5 && vPrev%2) f = 1;
break;
diff --git a/ext/bigdecimal/bigdecimal.h b/ext/bigdecimal/bigdecimal.h
index 62c89dce50..d8fa35d3c5 100644
--- a/ext/bigdecimal/bigdecimal.h
+++ b/ext/bigdecimal/bigdecimal.h
@@ -59,7 +59,7 @@ extern "C" {
#define VP_ROUND_HALF_DOWN 4
#define VP_ROUND_CEIL 5
#define VP_ROUND_FLOOR 6
-#define VP_ROUND_EVEN 7
+#define VP_ROUND_HALF_EVEN 7
#define VP_SIGN_NaN 0 /* NaN */
#define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */
@@ -121,7 +121,7 @@ VP_EXPORT double VpGetDoubleNegZero(void);
VP_EXPORT U_LONG VpGetPrecLimit(void);
VP_EXPORT U_LONG VpSetPrecLimit(U_LONG n);
-/* Computation mode */
+/* Round mode */
VP_EXPORT unsigned long VpGetRoundMode(void);
VP_EXPORT unsigned long VpSetRoundMode(unsigned long n);
diff --git a/ext/bigdecimal/bigdecimal_en.html b/ext/bigdecimal/bigdecimal_en.html
index ed192fca58..2d86adcc6b 100644
--- a/ext/bigdecimal/bigdecimal_en.html
+++ b/ext/bigdecimal/bigdecimal_en.html
@@ -156,18 +156,22 @@ Suppose the return value of the mode method is f,then
<B>[ROUND error control]</B><P>
Rounding operation can be controlled as:
<BLOCKQUOTE>
-f = BigDecimal::mode(BigDecimal::COMP_MODE,flag)
+f = BigDecimal::mode(BigDecimal::ROUND_MODE,flag)
</BLOCKQUOTE>
where flag must be one of:
<TABLE>
-<TR><TD>COMP_MODE_TRUNCATE</TD><TD>truncate</TD></TR>
-<TR><TD>COMP_MODE_ROUND</TD><TD>round,default</TD></TR>
-<TR><TD>COMP_MODE_CEIL</TD><TD>ceil</TD></TR>
-<TR><TD>COMP_MODE_FLOOR</TD><TD>floor</TD></TR>
-<TR><TD>COMP_MODE_EVEN</TD><TD>Banker's rounding</TD></TR>
+
+<TR><TD>ROUND_UP</TD><TD>round away from zero.</TD></TR>
+<TR><TD>ROUND_DOWN</TD><TD>round towards zero(truncate).</TD></TR>
+<TR><TD>ROUND_HALF_UP</TD><TD>round up if the digit &gt;= 5 otherwise truncated(default).</TD></TR>
+<TR><TD>ROUND_HALF_DOWN</TD><TD>round up if the digit &gt;= 6 otherwise truncated.</TD></TR>
+<TR><TD>ROUND_HALF_EVEN</TD><TD>round towards the even neighbor(Banker's rounding).
+<TR><TD>ROUND_CEILING</TD><TD>round towards positive infinity(ceil).</TD></TR>
+<TR><TD>ROUND_FLOOR</TD><TD>round towards negative infinity(floor).</TD></TR>
</TABLE>
-nil is returned if any argument is illegal.<BR>
-The digit location for rounding operation can not be specified by mode method,
+New rounding mode is returned,nil is returned if any argument is not an integer.
+Bad specification is ignored.<BR>
+The digit location for rounding operation can not be specified by this mode method,
use truncate/round/ceil/floor/add/sub/mult/div mthods for each instance instead.
</BLOCKQUOTE>
@@ -286,8 +290,8 @@ of the target digit can be given.<BR>
If n> 0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
<CODE><PRE>
- c = BigDecimal::new("1.23456").floor(4) # ==> 1.2345
- c = BigDecimal::new("15.23456").floor(-1) # ==> 10.0
+ c = BigDecimal("1.23456").floor(4) # ==> 1.2345
+ c = BigDecimal("15.23456").floor(-1) # ==> 10.0
</PRE></CODE>
</BLOCKQUOTE>
@@ -304,37 +308,33 @@ of the target digit can be given.<BR>
If n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
<CODE><PRE>
- c = BigDecimal::new("1.23456").ceil(4) # ==> 1.2346
- c = BigDecimal::new("15.23456").ceil(-1) # ==> 20.0
+ c = BigDecimal("1.23456").ceil(4) # ==> 1.2346
+ c = BigDecimal("15.23456").ceil(-1) # ==> 20.0
</PRE></CODE>
</BLOCKQUOTE>
<LI><B>round[(n[,b])]</B></LI><BLOCKQUOTE>
c = a.round<BR>
-round a to the nearest 1�D<BR>
+round a to the nearest 1(default)�D<BR>
<CODE><PRE>
c = BigDecimal("1.23456").round # ==> 1
c = BigDecimal("-1.23456").round # ==> -1
</PRE></CODE>
+The rounding operation changes according to BigDecimal::mode(BigDecimal::ROUND_MODE,flag) if specified.
As shown in the following example,an optional integer argument (n) specifying the position
of the target digit can be given.<BR>
-If n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
+If n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
<CODE><PRE>
c = BigDecimal::new("1.23456").round(4) # ==> 1.2346
c = BigDecimal::new("15.23456").round(-1) # ==> 20.0
</PRE></CODE>
-If the second optional argument b is given with the non-zero value(default is zero) then
-so called Banker's rounding is performed.<BR>
-Suppose the digit p is to be rounded,then:<BR>
- If p<5 then p is truncated<BR>
- If p>5 then p is rounded up<BR>
- If p is 5 then round up operation is taken only when the left hand side digit of p is odd.
+Rounding operation can be specified by setting the second optional argument b with the valid ROUND_MODE.<BR>
<CODE><PRE>
-c = BigDecimal::new("1.23456").round(3,1) # ==> 1.234
-c = BigDecimal::new("1.23356").round(3,1) # ==> 1.234
+c = BigDecimal::new("1.23456").round(3,BigDecimal::ROUND_HALF_EVEN) # ==> 1.234
+c = BigDecimal::new("1.23356").round(3,BigDecimal::ROUND_HALF_EVEN) # ==> 1.234
</PRE></CODE>
</BLOCKQUOTE>
@@ -728,11 +728,11 @@ As +,-,and * are always exact(no round operation is performed unless BigDecimal.
which means more momories are required to keep computation results.
But,the division such as c=1.0/3.0 will always be rounded.<BR>
-<H3>2. assign,add,sub,mult,div</H3>
+<H3>2. add,sub,mult,div</H3>
The length of the significant digits obtained from +,-,*,/
is always defined by that of right and left side of the operator.
To specify the length of the significant digits by your self,
-use methos assign,add,sub,mult,div.
+use methos add,sub,mult,div.
<CODE><PRE>
BigDecimal("2").div(3,12) # 2.0/3.0 => 0.6666666666 67E0
</PRE></CODE>
diff --git a/ext/bigdecimal/bigdecimal_ja.html b/ext/bigdecimal/bigdecimal_ja.html
index f78d63a9b6..31e852bd02 100644
--- a/ext/bigdecimal/bigdecimal_ja.html
+++ b/ext/bigdecimal/bigdecimal_ja.html
@@ -166,22 +166,26 @@ EXCEPTION_NaN���ݒ肳��Ă���Ƃ����Ӗ��ł��B<BR>
<B>[�ۂߏ����w��]</B><P>
�v�Z�r���̊ۂߑ���̎w�肪�ł��܂��B
<BLOCKQUOTE>
-f = BigDecimal::mode(BigDecimal::COMP_MODE,flag)
+f = BigDecimal::mode(BigDecimal::ROUND_MODE,flag)
</BLOCKQUOTE>
�̌`���Ŏw�肵�܂��B<BR>
�����ŁAflag �͈ȉ�(���ʓ��͑Ή�����C���X�^���X���\�b�h)�̈�‚��w�肵�܂��B
<TABLE>
-<TR><TD>COMP_MODE_TRUNCATE</TD><TD>�S�Đ؂�̂Ă܂�(truncate)�B</TD></TR>
-<TR><TD>COMP_MODE_ROUND</TD><TD>�l�̌ܓ����܂�(round�A�f�t�H���g)�B</TD></TR>
-<TR><TD>COMP_MODE_CEIL</TD><TD>���l�̑傫�����ɌJ��グ�܂�(ceil)�B</TD></TR>
-<TR><TD>COMP_MODE_FLOOR</TD><TD>���l�̏��������ɌJ�艺���܂�(floor)�B</TD></TR>
-<TR><TD>COMP_MODE_EVEN</TD><TD>�l�̘Z�����܂��B�T�̎��͏�ʂP������̎��̂݌J��グ�܂�(Banker's rounding)�B</TD></TR>
+<TR><TD>ROUND_UP</TD><TD>�S�Đ؂�グ�܂��B</TD></TR>
+<TR><TD>ROUND_DOWN</TD><TD>�S�Đ؂�̂Ă܂�(truncate)�B</TD></TR>
+<TR><TD>ROUND_HALF_UP</TD><TD>�l�̌ܓ����܂�(�f�t�H���g)�B</TD></TR>
+<TR><TD>ROUND_HALF_DOWN</TD><TD>�܎̘Z�����܂��B</TD></TR>
+<TR><TD>ROUND_HALF_EVEN</TD><TD>�l�̘Z�����܂��B�T�̎��͏�ʂP������̎��̂݌J��グ�܂�(Banker's rounding)�B</TD></TR>
+<TR><TD>ROUND_CEILING</TD><TD>���l�̑傫�����ɌJ��グ�܂�(ceil)�B</TD></TR>
+<TR><TD>ROUND_FLOOR</TD><TD>���l�̏��������ɌJ�艺���܂�(floor)�B</TD></TR>
+
</TABLE>
-�߂�l�͎w��O�� flag �̒l�ł��B
-�����ɐ������Ȃ����̂��w�肳�ꂽ�ꍇ�� nil ���Ԃ�܂��B<BR>
+�߂�l�͎w���� flag �̒l�ł��B
+�����ɐ��l�ȊO���w�肳�ꂽ�ꍇ�� nil ���Ԃ�܂��B�������Ȃ� ROUND_MODE ���w�肳�ꂽ�Ƃ���
+��������A����� ROUND_MODE ���Ԃ�܂��B<BR>
mode ���\�b�h�ł͊ۂߑ���̈ʒu�����[�U���w�肷�邱�Ƃ͂ł��܂���B
�ۂߑ���ƈʒu�������Ő��䂵�����ꍇ�� truncate/round/ceil/floor ��
-add/sub/mult �Ƃ������C���X�^���X���\�b�h���g�p���ĉ������B
+add/sub/mult/div �Ƃ������C���X�^���X���\�b�h���g�p���ĉ������B
</BLOCKQUOTE>
<LI><B>limit([n])</B></LI><BLOCKQUOTE>
���������BigDecimal�I�u�W�F�N�g�̍ő包����n���ɐ������܂��B
@@ -192,7 +196,7 @@ n ���w�肵�Ȃ��ꍇ�́A����̍ő包�����Ԃ�܂��B<BR>
�ۂߏ��������s����܂��B
�������A���ۂɂ� n ���኱�傫��
�������m�ۂ���܂��B�܂��Alimit �ɂ�錅��������(��������������)�A
-�C���X�^���X���\�b�h (truncate/round/ceil/floor/add/sub/mult) ���
+�C���X�^���X���\�b�h (truncate/round/ceil/floor/add/sub/mult/div) ���
�D�悳���̂Œ��ӂ��K�v�ł��B<BR>
mf = BigDecimal::limit(n)<BR>
</BLOCKQUOTE>
@@ -296,8 +300,8 @@ c = BigDecimal("-1.23456").floor # ==> -2
n>=0 �Ȃ�A�����_�ȉ� n+1 �ʂ̐����𑀍삵�܂�(�����_�ȉ����A�ő� n ���ɂ��܂�)�B<BR>
n �����̂Ƃ��͏����_�ȏ� n ���ڂ𑀍삵�܂�(�����_�ʒu���獶�ɏ��Ȃ��Ƃ� n �‚� 0 �����т܂�)�B<BR>
<CODE><PRE>
- c = BigDecimal::new("1.23456").floor(4) # ==> 1.2345
- c = BigDecimal::new("15.23456").floor(-1) # ==> 10.0
+ c = BigDecimal("1.23456").floor(4) # ==> 1.2345
+ c = BigDecimal("15.23456").floor(-1) # ==> 10.0
</PRE></CODE>
</BLOCKQUOTE>
@@ -313,32 +317,35 @@ c = BigDecimal("-1.23456").ceil # ==> -1
n>=0 �Ȃ�A�����_�ȉ� n+1 �ʂ̐����𑀍삵�܂�(�����_�ȉ����A�ő� n ���ɂ��܂�)�B<BR>
n �����̂Ƃ��͏����_�ȏ� n ���ڂ��𑀍삵�܂�(�����_�ʒu���獶�ɏ��Ȃ��Ƃ� n �‚� 0 �����т܂�)�B<BR>
<CODE><PRE>
- c = BigDecimal::new("1.23456").ceil(4) # ==> 1.2346
- c = BigDecimal::new("15.23456").ceil(-1) # ==> 20.0
+ c = BigDecimal("1.23456").ceil(4) # ==> 1.2346
+ c = BigDecimal("15.23456").ceil(-1) # ==> 20.0
</PRE></CODE>
</BLOCKQUOTE>
<LI><B>round[(n[,b])]</B></LI><BLOCKQUOTE>
c = a.round<BR>
-�����_�ȉ����ʂ̐����l�̌ܓ����Đ����iBigDecimal �l�j�ɂ��܂��B<BR>
+
+�N���X���\�b�h BigDecimal::mode(BigDecimal::ROUND_MODE,flag) �Ŏw�肵��
+ROUND_MODE �ɏ]���Ċۂߑ�������s���܂��B
+BigDecimal::mode(BigDecimal::ROUND_MODE,flag) �ʼn����w�肹���A���A����
+���w�肵�Ȃ��ꍇ�́u�����_�ȉ����ʂ̐����l�̌ܓ����Đ����iBigDecimal �l�j�v�ɂ��܂��B<BR>
<CODE><PRE>
c = BigDecimal("1.23456").round # ==> 1
c = BigDecimal("-1.23456").round # ==> -1
</PRE></CODE>
�ȉ��̂悤�Ɉ�����^���āA�����_�ȉ� n+1 �ʂ̐����𑀍삷�邱�Ƃ��ł��܂��B<BR>
-n �����̎��́A�����_�ȉ� n+1 �ʂ̐������l�̌ܓ����܂�(�����_�ȉ����A�ő� n ���ɂ��܂�)�B<BR>
-n �����̂Ƃ��͏����_�ȏ� n ���ڂ��𑀍삵�܂�(�����_�ʒu���獶�ɏ��Ȃ��Ƃ� n �‚� 0 �����т܂�)�B
+n �����̎��́A�����_�ȉ� n+1 �ʂ̐������ۂ߂܂�(�����_�ȉ����A�ő� n ���ɂ��܂�)�B<BR>
+n �����̂Ƃ��͏����_�ȏ� n ���ڂ��ۂ߂܂�(�����_�ʒu���獶�ɏ��Ȃ��Ƃ� n �‚� 0 �����т܂�)�B
<CODE><PRE>
-c = BigDecimal::new("1.23456").round(4) # ==> 1.2346
-c = BigDecimal::new("15.23456").round(-1) # ==> 20.0
+c = BigDecimal("1.23456").round(4) # ==> 1.2346
+c = BigDecimal("15.23456").round(-1) # ==> 20.0
</PRE></CODE>
-�Q�Ԗڂ̈����i�f�t�H���g�� 0�j�Ƀ[���ȊO���w�肷��ƁA������ Banker's rounding �ɂȂ�܂��B<BR>
- Banker's rounding �Ƃ́A�l�̌ܓ����鐔���� p �Ƃ��āAp &lt; 5 �Ȃ�؂�̂� p &gt; 5 �Ȃ�؂�グ�A
-p �����傤�ǂT�̂Ƃ������͐؂�グ��̐����{�P�������ɂȂ�Ƃ������؂�グ�܂��B
+�Q�Ԗڂ̈������w�肷��ƁABigDecimal#mode �̎w��𖳎����āA�w�肳�ꂽ���@��
+�ۂߑ�������s���܂��B
<CODE><PRE>
-c = BigDecimal::new("1.23456").round(3,1) # ==> 1.234
-c = BigDecimal::new("1.23356").round(3,1) # ==> 1.234
+c = BigDecimal("1.23456").round(3,BigDecimal::ROUND_HALF_EVEN) # ==> 1.234
+c = BigDecimal("1.23356").round(3,BigDecimal::ROUND_HALF_EVEN) # ==> 1.234
</PRE></CODE>
</BLOCKQUOTE>
@@ -349,8 +356,8 @@ c = a.truncate<BR>
n �����̎��́A�����_�ȉ� n+1 �ʂ̐�����؂�̂Ă܂�(�����_�ȉ����A�ő� n ���ɂ��܂�)�B
n �����̂Ƃ��͏����_�ȏ� n ���ڂ��𑀍삵�܂�(�����_�ʒu���獶�ɏ��Ȃ��Ƃ� n �‚� 0 �����т܂�)�B<BR>
<CODE><PRE>
-c = BigDecimal::new("1.23456").truncate(4) # ==> 1.2345
-c = BigDecimal::new("15.23456").truncate(-1) # ==> 10.0
+c = BigDecimal("1.23456").truncate(4) # ==> 1.2345
+c = BigDecimal("15.23456").truncate(-1) # ==> 10.0
</PRE></CODE>
</BLOCKQUOTE>