📄 math::bigint.3
字号:
\& after the decimal point\& * Math::BigFloat uses Math::BigInt internally, but setting A or P inside\& Math::BigInt as globals does not tamper with the parts of a BigFloat.\& A flag is used to mark all Math::BigFloat numbers as \*(Aqnever round\*(Aq..Ve.IP "Precedence" 2.IX Item "Precedence".Vb 10\& * It only makes sense that a number has only one of A or P at a time.\& If you set either A or P on one object, or globally, the other one will\& be automatically cleared.\& * If two objects are involved in an operation, and one of them has A in\& effect, and the other P, this results in an error (NaN).\& * A takes precedence over P (Hint: A comes before P).\& If neither of them is defined, nothing is used, i.e. the result will have\& as many digits as it can (with an exception for fdiv/fsqrt) and will not\& be rounded.\& * There is another setting for fdiv() (and thus for fsqrt()). If neither of\& A or P is defined, fdiv() will use a fallback (F) of $div_scale digits.\& If either the dividend\*(Aqs or the divisor\*(Aqs mantissa has more digits than\& the value of F, the higher value will be used instead of F.\& This is to limit the digits (A) of the result (just consider what would\& happen with unlimited A and P in the case of 1/3 :\-)\& * fdiv will calculate (at least) 4 more digits than required (determined by\& A, P or F), and, if F is not used, round the result\& (this will still fail in the case of a result like 0.12345000000001 with A\& or P of 5, but this can not be helped \- or can it?)\& * Thus you can have the math done by on Math::Big* class in two modi:\& + never round (this is the default):\& This is done by setting A and P to undef. No math operation\& will round the result, with fdiv() and fsqrt() as exceptions to guard\& against overflows. You must explicitly call bround(), bfround() or\& round() (the latter with parameters).\& Note: Once you have rounded a number, the settings will \*(Aqstick\*(Aq on it\& and \*(Aqinfect\*(Aq all other numbers engaged in math operations with it, since\& local settings have the highest precedence. So, to get SaferRound[tm],\& use a copy() before rounding like this:\&\& $x = Math::BigFloat\->new(12.34);\& $y = Math::BigFloat\->new(98.76);\& $z = $x * $y; # 1218.6984\& print $x\->copy()\->fround(3); # 12.3 (but A is now 3!)\& $z = $x * $y; # still 1218.6984, without\& # copy would have been 1210!\&\& + round after each op:\& After each single operation (except for testing like is_zero()), the\& method round() is called and the result is rounded appropriately. By\& setting proper values for A and P, you can have all\-the\-same\-A or\& all\-the\-same\-P modes. For example, Math::Currency might set A to undef,\& and P to \-2, globally.\&\& ?Maybe an extra option that forbids local A & P settings would be in order,\& ?so that intermediate rounding does not \*(Aqpoison\*(Aq further math?.Ve.IP "Overriding globals" 2.IX Item "Overriding globals".Vb 10\& * you will be able to give A, P and R as an argument to all the calculation\& routines; the second parameter is A, the third one is P, and the fourth is\& R (shift right by one for binary operations like badd). P is used only if\& the first parameter (A) is undefined. These three parameters override the\& globals in the order detailed as follows, i.e. the first defined value\& wins:\& (local: per object, global: global default, parameter: argument to sub)\& + parameter A\& + parameter P\& + local A (if defined on both of the operands: smaller one is taken)\& + local P (if defined on both of the operands: bigger one is taken)\& + global A\& + global P\& + global F\& * fsqrt() will hand its arguments to fdiv(), as it used to, only now for two\& arguments (A and P) instead of one.Ve.IP "Local settings" 2.IX Item "Local settings".Vb 5\& * You can set A or P locally by using C<< $x\->accuracy() >> or\& C<< $x\->precision() >>\& and thus force different A and P for different objects/numbers.\& * Setting A or P this way immediately rounds $x to the new value.\& * C<< $x\->accuracy() >> clears C<< $x\->precision() >>, and vice versa..Ve.IP "Rounding" 2.IX Item "Rounding".Vb 10\& * the rounding routines will use the respective global or local settings.\& fround()/bround() is for accuracy rounding, while ffround()/bfround()\& is for precision\& * the two rounding functions take as the second parameter one of the\& following rounding modes (R):\& \*(Aqeven\*(Aq, \*(Aqodd\*(Aq, \*(Aq+inf\*(Aq, \*(Aq\-inf\*(Aq, \*(Aqzero\*(Aq, \*(Aqtrunc\*(Aq, \*(Aqcommon\*(Aq\& * you can set/get the global R by using C<< Math::SomeClass\->round_mode() >>\& or by setting C<< $Math::SomeClass::round_mode >>\& * after each operation, C<< $result\->round() >> is called, and the result may\& eventually be rounded (that is, if A or P were set either locally,\& globally or as parameter to the operation)\& * to manually round a number, call C<< $x\->round($A,$P,$round_mode); >>\& this will round the number by using the appropriate rounding function\& and then normalize it.\& * rounding modifies the local settings of the number:\&\& $x = Math::BigFloat\->new(123.456);\& $x\->accuracy(5);\& $x\->bround(4);\&\& Here 4 takes precedence over 5, so 123.5 is the result and $x\->accuracy()\& will be 4 from now on..Ve.IP "Default values" 2.IX Item "Default values".Vb 4\& * R: \*(Aqeven\*(Aq\& * F: 40\& * A: undef\& * P: undef.Ve.IP "Remarks" 2.IX Item "Remarks".Vb 5\& * The defaults are set up so that the new code gives the same results as\& the old code (except in a few cases on fdiv):\& + Both A and P are undefined and thus will not be used for rounding\& after each operation.\& + round() is thus a no\-op, unless given extra parameters A and P.Ve.SH "Infinity and Not a Number".IX Header "Infinity and Not a Number"While BigInt has extensive handling of inf and NaN, certain quirks remain..IP "\fIoct()\fR/\fIhex()\fR" 2.IX Item "oct()/hex()"These perl routines currently (as of Perl v.5.8.6) cannot handle passedinf..Sp.Vb 9\& te@linux:~> perl \-wle \*(Aqprint 2 ** 3333\*(Aq\& inf\& te@linux:~> perl \-wle \*(Aqprint 2 ** 3333 == 2 ** 3333\*(Aq\& 1\& te@linux:~> perl \-wle \*(Aqprint oct(2 ** 3333)\*(Aq\& 0\& te@linux:~> perl \-wle \*(Aqprint hex(2 ** 3333)\*(Aq\& Illegal hexadecimal digit \*(Aqi\*(Aq ignored at \-e line 1.\& 0.Ve.SpThe same problems occur if you pass them Math::BigInt\->\fIbinf()\fR objects. Sinceoverloading these routines is not possible, this cannot be fixed from BigInt..IP "==, !=, <, >, <=, >= with NaNs" 2.IX Item "==, !=, <, >, <=, >= with NaNs"BigInt's \fIbcmp()\fR routine currently returns undef to signal that a NaN wasinvolved in a comparison. However, the overload code turns that intoeither 1 or '' and thus operations like \f(CW\*(C`NaN != NaN\*(C'\fR might returnwrong values..IP "log(\-inf)" 2.IX Item "log(-inf)"\&\f(CW\*(C`log(\-inf)\*(C'\fR is highly weird. Since log(\-x)=pi*i+log(x), thenlog(\-inf)=pi*i+inf. However, since the imaginary part is finite, the realinfinity \*(L"overshadows\*(R" it, so the number might as well just be infinity.However, the result is a complex number, and since BigInt/BigFloat can onlyhave real numbers as results, the result is NaN..IP "\fIexp()\fR, \fIcos()\fR, \fIsin()\fR, \fIatan2()\fR" 2.IX Item "exp(), cos(), sin(), atan2()"These all might have problems handling infinity right..SH "INTERNALS".IX Header "INTERNALS"The actual numbers are stored as unsigned big integers (with seperate sign)..PPYou should neither care about nor depend on the internal representation; itmight change without notice. Use \fB\s-1ONLY\s0\fR method calls like \f(CW\*(C`$x\->sign();\*(C'\fRinstead relying on the internal representation..Sh "\s-1MATH\s0 \s-1LIBRARY\s0".IX Subsection "MATH LIBRARY"Math with the numbers is done (by default) by a module called\&\f(CW\*(C`Math::BigInt::Calc\*(C'\fR. This is equivalent to saying:.PP.Vb 1\& use Math::BigInt lib => \*(AqCalc\*(Aq;.Ve.PPYou can change this by using:.PP.Vb 1\& use Math::BigInt lib => \*(AqBitVect\*(Aq;.Ve.PPThe following would first try to find Math::BigInt::Foo, thenMath::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:.PP.Vb 1\& use Math::BigInt lib => \*(AqFoo,Math::BigInt::Bar\*(Aq;.Ve.PPSince Math::BigInt::GMP is in almost all cases faster than Calc (especially inmath involving really big numbers, where it is \fBmuch\fR faster), and there isno penalty if Math::BigInt::GMP is not installed, it is a good idea to alwaysuse the following:.PP.Vb 1\& use Math::BigInt lib => \*(AqGMP\*(Aq;.Ve.PPDifferent low-level libraries use different formats to store thenumbers. You should \fB\s-1NOT\s0\fR depend on the number having a specific formatinternally..PPSee the respective math library module documentation for further details..Sh "\s-1SIGN\s0".IX Subsection "SIGN"The sign is either '+', '\-', 'NaN', '+inf' or '\-inf'..PPA sign of 'NaN' is used to represent the result when input arguments are notnumbers or as a result of 0/0. '+inf' and '\-inf' represent plus respectivelyminus infinity. You will get '+inf' when dividing a positive number by 0, and\&'\-inf' when dividing any negative number by 0..Sh "\fImantissa()\fP, \fIexponent()\fP and \fIparts()\fP".IX Subsection "mantissa(), exponent() and parts()"\&\f(CW\*(C`mantissa()\*(C'\fR and \f(CW\*(C`exponent()\*(C'\fR return the said parts of the BigInt suchthat:.PP.Vb 4\& $m = $x\->mantissa();\& $e = $x\->exponent();\& $y = $m * ( 10 ** $e );\& print "ok\en" if $x == $y;.Ve.PP\&\f(CW\*(C`($m,$e) = $x\->parts()\*(C'\fR is just a shortcut that gives you both of themin one go. Both the returned mantissa and exponent have a sign..PPCurrently, for BigInts \f(CW$e\fR is always 0, except +inf and \-inf, where it is\&\f(CW\*(C`+inf\*(C'\fR; and for NaN, where it is \f(CW\*(C`NaN\*(C'\fR; and for \f(CW\*(C`$x == 0\*(C'\fR, where it is \f(CW1\fR(to be compatible with Math::BigFloat's internal representation of a zero as\&\f(CW0E1\fR)..PP\&\f(CW$m\fR is currently just a copy of the original number. The relation between\&\f(CW$e\fR and \f(CW$m\fR will stay always the same, though their real values mightchange..SH "EXAMPLES".IX Header "EXAMPLES".Vb 1\& use Math::BigInt;\&\& sub bint { Math::BigInt\->new(shift); }\&\& $x = Math::BigInt\->bstr("1234") # string "1234"\& $x = "$x"; # same as bstr()\& $x = Math::BigInt\->bneg("1234"); # BigInt "\-1234"\& $x = Math::BigInt\->babs("\-12345"); # BigInt "12345"\& $x = Math::BigInt\->bnorm("\-0.00"); # BigInt "0"\& $x = bint(1) + bint(2); # BigInt "3"\& $x = bint(1) + "2"; # ditto (auto\-BigIntify of "2")\& $x = bint(1); # BigInt "1"\& $x = $x + 5 / 2; # BigInt "3"\& $x = $x ** 3; # BigInt "27"\& $x *= 2; # BigInt "54"\& $x = Math::BigInt\->new(0); # BigInt "0"\& $x\-\-; # BigInt "\-1"\& $x = Math::BigInt\->badd(4,5) # BigInt "9"\& print $x\->bsstr(); # 9e+0.Ve.PPExamples for rounding:.PP.Vb 2\& use Math::BigFloat;\& use Test;\&\& $x = Math::BigFloat\->new(123.4567);\& $y = Math::BigFloat\->new(123.456789);\& Math::BigFloat\->accuracy(4); # no more A than 4\&\& ok ($x\->copy()\->fround(),123.4); # even rounding\& print $x\->copy()\->fround(),"\en"; # 123.4\& Math::BigFloat\->round_mode(\*(Aqodd\*(Aq); # round to odd\& print $x\->copy()\->fround(),"\en"; # 123.5\& Math::BigFloat\->accuracy(5); # no more A than 5\& Math::BigFloat\->round_mode(\*(Aqodd\*(Aq); # round to odd\& print $x\->copy()\->fround(),"\en"; # 123.46\& $y = $x\->copy()\->fround(4),"\en"; # A = 4: 123.4\& print "$y, ",$y\->accuracy(),"\en"; # 123.4, 4\&\& Math::BigFloat\->accuracy(undef); # A not important now\& Math::BigFloat\->precision(2); # P important\& print $x\->copy()\->bnorm(),"\en"; # 123.46\& print $x\->copy()\->fround(),"\en"; # 123.46.Ve.PPExamples for converting:.PP.Vb 2\& my $x = Math::BigInt\->new(\*(Aq0b1\*(Aq.\*(Aq01\*(Aq x 123);\& print "bin: ",$x\->as_bin()," hex:",$x\->as_hex()," dec: ",$x,"\en";.Ve.SH "Autocreating constants".IX Header "Autocreating constants"After \f(CW\*(C`use Math::BigInt \*(Aq:constant\*(Aq\*(C'\fR all the \fBinteger\fR decimal, hexadecimaland binary constants in the given scope are converted to \f(CW\*(C`Math::BigInt\*(C'\fR.This conversion happens at compile time..PPIn particular,.PP.Vb 1\& perl \-MMath::BigInt=:constant \-e \*(Aqprint 2**100,"\en"\*(Aq.Ve.PPprints the integer value of \f(CW\*(C`2**100\*(C'\fR. Note that without conversion of constants the expression 2**100 will be calculated as perl scalar..PPPlease note that strings and floating point constants are not affected,so that.PP.Vb 1\& use Math::BigInt qw/:constant/;\&\& $x = 1234567890123456789012345678901234567890\& + 123456789123456789;\& $y = \*(Aq1234567890123456789012345678901234567890\*(Aq\& + \*(Aq123456789123456789\*(Aq;.Ve.PPdo not work. You need an explicit Math::BigInt\->\fInew()\fR around one of theoperands. You should also quote large constants to protect loss of precision:.PP.Vb 1\& use Math::BigInt;\&\& $x = Math::BigInt\->new(\*(Aq1234567889123456789123456789123456789\*(Aq);.Ve.PPWithout the quotes Perl would convert the large number to a floating pointconstant at compile time and then hand the result to BigInt, which results inan truncated result or a NaN..PPThis also applies to integers that look like floating point constants:.PP.Vb 1\& use Math::BigInt \*(Aq:constant\*(Aq;\&\& print ref(123e2),"\en";\& print ref(123.2e2),"\en";.Ve.PPwill print nothing but newlines. Use either bignum or Math::BigFloatto get this to work..SH "PERFORMANCE".IX Header "PERFORMANCE"Using the form \f(CW$x\fR += \f(CW$y\fR; etc over \f(CW$x\fR = \f(CW$x\fR + \f(CW$y\fR is faster, since a copy of \f(CW$x\fRmust be made in the second case. For long numbers, the copy can eat
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -