integerPower sets d = x**y. d and x must not point to the same Decimal.
(d, x *Decimal, y *BigInt)
| 997 | |
| 998 | // integerPower sets d = x**y. d and x must not point to the same Decimal. |
| 999 | func (c *Context) integerPower(d, x *Decimal, y *BigInt) (Condition, error) { |
| 1000 | // See: https://en.wikipedia.org/wiki/Exponentiation_by_squaring. |
| 1001 | |
| 1002 | var b BigInt |
| 1003 | b.Set(y) |
| 1004 | neg := b.Sign() < 0 |
| 1005 | if neg { |
| 1006 | b.Abs(&b) |
| 1007 | } |
| 1008 | |
| 1009 | var n Decimal |
| 1010 | n.Set(x) |
| 1011 | z := d |
| 1012 | z.Set(decimalOne) |
| 1013 | ed := MakeErrDecimal(c) |
| 1014 | for b.Sign() > 0 { |
| 1015 | if b.Bit(0) == 1 { |
| 1016 | ed.Mul(z, z, &n) |
| 1017 | } |
| 1018 | b.Rsh(&b, 1) |
| 1019 | |
| 1020 | // Only compute the next n if we are going to use it. Otherwise n can overflow |
| 1021 | // on the last iteration causing this to error. |
| 1022 | if b.Sign() > 0 { |
| 1023 | ed.Mul(&n, &n, &n) |
| 1024 | } |
| 1025 | if err := ed.Err(); err != nil { |
| 1026 | // In the negative case, convert overflow to underflow. |
| 1027 | if neg { |
| 1028 | ed.Flags = ed.Flags.negateOverflowFlags() |
| 1029 | } |
| 1030 | return ed.Flags, err |
| 1031 | } |
| 1032 | } |
| 1033 | |
| 1034 | if neg { |
| 1035 | ed.Quo(z, decimalOne, z) |
| 1036 | } |
| 1037 | return ed.Flags, ed.Err() |
| 1038 | } |
| 1039 | |
| 1040 | // Pow sets d = x**y. |
| 1041 | func (c *Context) Pow(d, x, y *Decimal) (Condition, error) { |