Files
Android-pyApi/android_pyapi/java/math.py
T
shuiyu1123 bfe27fdc08 feat: Android-pyApi v1.0 - 全面翻译 Android SDK API 为 Python
52 个模块覆盖 Android + Java + org.json 标准库
2026-06-24 11:16:16 +00:00

683 lines
20 KiB
Python

"""
Java math standard library APIs implemented in Python.
java.math package - BigInteger, BigDecimal, MathContext, RoundingMode.
"""
from .._core import Stub
from .lang import Comparable
from decimal import (
Decimal as _Decimal,
ROUND_DOWN as _DEC_ROUND_DOWN,
ROUND_HALF_UP as _DEC_ROUND_HALF_UP,
ROUND_HALF_EVEN as _DEC_ROUND_HALF_EVEN,
ROUND_UP as _DEC_ROUND_UP,
ROUND_CEILING as _DEC_ROUND_CEILING,
ROUND_FLOOR as _DEC_ROUND_FLOOR,
ROUND_HALF_DOWN as _DEC_ROUND_HALF_DOWN,
localcontext as _local_context,
getcontext as _get_context,
)
import random as _random
import math as _py_math
import sys as _sys
__all__ = [
"BigInteger", "BigDecimal", "MathContext", "RoundingMode",
]
# ============================================================
# RoundingMode
# ============================================================
class RoundingMode(Stub):
UP = 0
DOWN = 1
CEILING = 2
FLOOR = 3
HALF_UP = 4
HALF_DOWN = 5
HALF_EVEN = 6
UNNECESSARY = 7
_names = {
0: "UP", 1: "DOWN", 2: "CEILING", 3: "FLOOR",
4: "HALF_UP", 5: "HALF_DOWN", 6: "HALF_EVEN", 7: "UNNECESSARY",
}
_py_map = {
0: _DEC_ROUND_UP,
1: _DEC_ROUND_DOWN,
2: _DEC_ROUND_CEILING,
3: _DEC_ROUND_FLOOR,
4: _DEC_ROUND_HALF_UP,
5: _DEC_ROUND_HALF_DOWN,
6: _DEC_ROUND_HALF_EVEN,
7: _DEC_ROUND_HALF_EVEN, # closest approximation
}
def __init__(self, value):
super().__init__()
self._value = value
def toString(self):
return self._names.get(self._value, "UNKNOWN")
# ============================================================
# MathContext
# ============================================================
class MathContext(Stub):
UNLIMITED = None
DECIMAL32 = None
DECIMAL64 = None
DECIMAL128 = None
def __init__(self, *args):
super().__init__()
if len(args) == 1:
if isinstance(args[0], str):
s = args[0].strip().lower()
if s == "precision=7 roundingmode=half_even":
self._precision = 7
self._rounding_mode = RoundingMode.HALF_EVEN
elif s == "precision=16 roundingmode=half_even":
self._precision = 16
self._rounding_mode = RoundingMode.HALF_EVEN
elif s == "precision=34 roundingmode=half_even":
self._precision = 34
self._rounding_mode = RoundingMode.HALF_EVEN
else:
self._precision = 0
self._rounding_mode = RoundingMode.HALF_UP
else:
self._precision = int(args[0])
self._rounding_mode = RoundingMode.HALF_UP
elif len(args) == 2:
self._precision = int(args[0])
self._rounding_mode = args[1]
def getPrecision(self):
return self._precision
def getRoundingMode(self):
return self._rounding_mode
def equals(self, other):
if isinstance(other, MathContext):
return (self._precision == other._precision and
self._rounding_mode == other._rounding_mode)
return False
def hashCode(self):
return hash((self._precision, self._rounding_mode)) & 0x7FFFFFFF
def toString(self):
return f"precision={self._precision} roundingMode={self._rounding_mode.toString()}"
MathContext.UNLIMITED = MathContext(0)
MathContext.DECIMAL32 = MathContext(7, RoundingMode.HALF_EVEN)
MathContext.DECIMAL64 = MathContext(16, RoundingMode.HALF_EVEN)
MathContext.DECIMAL128 = MathContext(34, RoundingMode.HALF_EVEN)
# ============================================================
# BigInteger
# ============================================================
class BigInteger(Comparable):
ZERO = None
ONE = None
TEN = None
def __init__(self, *args):
super().__init__()
if len(args) == 0:
self._value = 0
elif len(args) == 1:
if isinstance(args[0], str):
self._value = int(str(args[0]))
elif isinstance(args[0], bytes):
self._value = int.from_bytes(args[0], byteorder="big", signed=True)
elif isinstance(args[0], bytearray):
self._value = int.from_bytes(bytes(args[0]), byteorder="big", signed=True)
elif isinstance(args[0], int):
self._value = args[0]
elif isinstance(args[0], BigInteger):
self._value = args[0]._value
else:
self._value = int(args[0])
elif len(args) == 2:
if isinstance(args[1], _random.Random):
bit_length, rng = args
self._value = rng.getrandbits(bit_length)
elif isinstance(args[1], int):
val_str, radix = args
self._value = int(str(val_str), radix)
else:
self._value = int.from_bytes(bytes(args[0]), byteorder="big", signed=True)
else:
self._value = 0
@staticmethod
def valueOf(val):
if isinstance(val, int):
if val == 0:
return BigInteger.ZERO
if val == 1:
return BigInteger.ONE
if val == 10:
return BigInteger.TEN
return BigInteger(val)
def add(self, other):
if isinstance(other, BigInteger):
return BigInteger(self._value + other._value)
return BigInteger(self._value + int(other))
def subtract(self, other):
if isinstance(other, BigInteger):
return BigInteger(self._value - other._value)
return BigInteger(self._value - int(other))
def multiply(self, other):
if isinstance(other, BigInteger):
return BigInteger(self._value * other._value)
return BigInteger(self._value * int(other))
def divide(self, other):
if isinstance(other, BigInteger):
return BigInteger(self._value // other._value)
return BigInteger(self._value // int(other))
def pow(self, exponent):
return BigInteger(self._value ** exponent)
def gcd(self, other):
return BigInteger(_py_math.gcd(self._value, other._value if isinstance(other, BigInteger) else int(other)))
def abs(self):
return BigInteger(abs(self._value))
def negate(self):
return BigInteger(-self._value)
def signum(self):
if self._value > 0:
return 1
if self._value < 0:
return -1
return 0
def mod(self, m):
if isinstance(m, BigInteger):
return BigInteger(self._value % m._value)
return BigInteger(self._value % int(m))
def remainder(self, other):
if isinstance(other, BigInteger):
return BigInteger(self._value % other._value)
return BigInteger(self._value % int(other))
def and_(self, other):
return BigInteger(self._value & (other._value if isinstance(other, BigInteger) else int(other)))
def or_(self, other):
return BigInteger(self._value | (other._value if isinstance(other, BigInteger) else int(other)))
def xor(self, other):
return BigInteger(self._value ^ (other._value if isinstance(other, BigInteger) else int(other)))
def not_(self):
return BigInteger(~self._value)
def andNot(self, other):
return BigInteger(self._value & ~(other._value if isinstance(other, BigInteger) else int(other)))
def shiftLeft(self, n):
return BigInteger(self._value << n)
def shiftRight(self, n):
return BigInteger(self._value >> n)
def getLowestSetBit(self):
if self._value == 0:
return -1
return (self._value & -self._value).bit_length() - 1
def bitLength(self):
if self._value == 0:
return 0
return self._value.bit_length()
def bitCount(self):
return bin(self._value & ((1 << self.bitLength()) - 1) if self._value >= 0 else self._value).count("1")
def isProbablePrime(self, certainty):
if abs(self._value) < 2:
return False
if abs(self._value) == 2 or abs(self._value) == 3:
return True
if self._value % 2 == 0:
return False
d = self._value - 1
s = 0
while d % 2 == 0:
d //= 2
s += 1
for _ in range(min(certainty, 20)):
a = _random.randrange(2, min(self._value - 1, 1000000))
x = pow(a, d, self._value)
if x == 1 or x == self._value - 1:
continue
for _ in range(s - 1):
x = pow(x, 2, self._value)
if x == self._value - 1:
break
else:
return False
return True
def nextProbablePrime(self):
v = self._value + 1
if v < 3:
return BigInteger(2) if v <= 2 else BigInteger(3)
while True:
if v % 2 == 0:
v += 1
for i in range(3, int(_py_math.sqrt(v)) + 1, 2):
if v % i == 0:
break
else:
return BigInteger(v)
v += 2
def compareTo(self, other):
if isinstance(other, BigInteger):
return (self._value > other._value) - (self._value < other._value)
return -1
def equals(self, other):
if isinstance(other, BigInteger):
return self._value == other._value
return False
def toByteArray(self):
if self._value == 0:
return b"\x00"
byte_length = (self._value.bit_length() + 8) // 8
return self._value.to_bytes(byte_length, byteorder="big", signed=True)
def toString(self, radix=10):
if radix == 10:
return str(self._value)
if radix == 16:
return hex(self._value)[2:]
if radix == 8:
return oct(self._value)[2:]
if radix == 2:
return bin(self._value)[2:]
return str(self._value)
def intValue(self):
return self._value & 0xFFFFFFFF
def longValue(self):
return self._value
def floatValue(self):
return float(self._value)
def doubleValue(self):
return float(self._value)
def min(self, other):
return BigInteger(min(self._value, other._value if isinstance(other, BigInteger) else int(other)))
def max(self, other):
return BigInteger(max(self._value, other._value if isinstance(other, BigInteger) else int(other)))
def modPow(self, exponent, m):
if isinstance(exponent, BigInteger):
exp_val = exponent._value
else:
exp_val = int(exponent)
mod_val = m._value if isinstance(m, BigInteger) else int(m)
return BigInteger(pow(self._value, exp_val, mod_val))
def modInverse(self, m):
mod_val = m._value if isinstance(m, BigInteger) else int(m)
return BigInteger(pow(self._value, -1, mod_val))
def divideAndRemainder(self, other):
if isinstance(other, BigInteger):
divisor = other._value
else:
divisor = int(other)
q = self._value // divisor
r = self._value % divisor
return [BigInteger(q), BigInteger(r)]
def __int__(self):
return self._value
def __str__(self):
return str(self._value)
def __neg__(self):
return self.negate()
def __abs__(self):
return self.abs()
def __add__(self, other):
return self.add(other)
def __sub__(self, other):
return self.subtract(other)
def __mul__(self, other):
return self.multiply(other)
def __truediv__(self, other):
return self.divide(other)
def __floordiv__(self, other):
return self.divide(other)
def __mod__(self, other):
return self.mod(other)
def __pow__(self, other):
return self.pow(other)
def __and__(self, other):
return self.and_(other)
def __or__(self, other):
return self.or_(other)
def __xor__(self, other):
return self.xor(other)
def __invert__(self):
return self.not_()
def __lshift__(self, n):
return self.shiftLeft(n)
def __rshift__(self, n):
return self.shiftRight(n)
BigInteger.ZERO = BigInteger(0)
BigInteger.ONE = BigInteger(1)
BigInteger.TEN = BigInteger(10)
# ============================================================
# BigDecimal
# ============================================================
class BigDecimal(Comparable):
ZERO = None
ONE = None
TEN = None
ROUND_UP = 0
ROUND_DOWN = 1
ROUND_CEILING = 2
ROUND_FLOOR = 3
ROUND_HALF_UP = 4
ROUND_HALF_DOWN = 5
ROUND_HALF_EVEN = 6
ROUND_UNNECESSARY = 7
_round_map = {
0: _DEC_ROUND_UP,
1: _DEC_ROUND_DOWN,
2: _DEC_ROUND_CEILING,
3: _DEC_ROUND_FLOOR,
4: _DEC_ROUND_HALF_UP,
5: _DEC_ROUND_HALF_DOWN,
6: _DEC_ROUND_HALF_EVEN,
7: _DEC_ROUND_HALF_EVEN,
}
def __init__(self, *args):
super().__init__()
if len(args) == 1:
val = args[0]
if isinstance(val, str):
self._dec = _Decimal(str(val))
elif isinstance(val, float):
self._dec = _Decimal(repr(val))
elif isinstance(val, int):
self._dec = _Decimal(val)
elif isinstance(val, BigInteger):
self._dec = _Decimal(val._value)
elif isinstance(val, BigDecimal):
self._dec = _Decimal(val._dec)
elif isinstance(val, _Decimal):
self._dec = val
else:
self._dec = _Decimal(str(val))
elif len(args) == 2:
val, mc = args
if isinstance(val, str):
self._dec = _Decimal(str(val))
elif isinstance(val, float):
self._dec = _Decimal(repr(val))
else:
self._dec = _Decimal(val)
if mc and hasattr(mc, 'getPrecision') and mc.getPrecision() > 0:
self._dec = +self._dec
@staticmethod
def valueOf(val):
if isinstance(val, int):
if val == 0:
return BigDecimal.ZERO
if val == 1:
return BigDecimal.ONE
if val == 10:
return BigDecimal.TEN
if isinstance(val, float):
return BigDecimal(repr(val))
return BigDecimal(val)
def add(self, other):
if isinstance(other, BigDecimal):
return BigDecimal(self._dec + other._dec)
return BigDecimal(self._dec + _Decimal(str(other)))
def subtract(self, other):
if isinstance(other, BigDecimal):
return BigDecimal(self._dec - other._dec)
return BigDecimal(self._dec - _Decimal(str(other)))
def multiply(self, other):
if isinstance(other, BigDecimal):
return BigDecimal(self._dec * other._dec)
return BigDecimal(self._dec * _Decimal(str(other)))
def divide(self, *args):
if len(args) == 1:
other = args[0]
if isinstance(other, BigDecimal):
return BigDecimal(self._dec / other._dec)
return BigDecimal(self._dec / _Decimal(str(other)))
elif len(args) == 2:
other, rounding_mode = args
if isinstance(other, BigDecimal):
result = self._dec / other._dec
else:
result = self._dec / _Decimal(str(other))
return BigDecimal(result)
elif len(args) == 3:
other, scale, rounding_mode = args
if isinstance(other, BigDecimal):
result = self._dec / other._dec
else:
result = self._dec / _Decimal(str(other))
rounded = BigDecimal(result)
return rounded.setScale(scale, rounding_mode)
def divideToIntegralValue(self, other):
if isinstance(other, BigDecimal):
return BigDecimal(int(self._dec / other._dec))
return BigDecimal(int(self._dec / _Decimal(str(other))))
def remainder(self, other):
if isinstance(other, BigDecimal):
return BigDecimal(self._dec % other._dec)
return BigDecimal(self._dec % _Decimal(str(other)))
def pow(self, n):
return BigDecimal(self._dec ** n)
def abs(self):
return BigDecimal(abs(self._dec))
def negate(self):
return BigDecimal(-self._dec)
def signum(self):
if self._dec > 0:
return 1
if self._dec < 0:
return -1
return 0
def scale(self):
return abs(self._dec.as_tuple().exponent)
def precision(self):
return len(self._dec.as_tuple().digits)
def round(self, mc):
if mc.getPrecision() > 0:
with _local_context() as ctx:
ctx.prec = mc.getPrecision()
return BigDecimal(+self._dec)
return BigDecimal(self._dec)
def setScale(self, new_scale, rounding_mode=None):
if rounding_mode is None:
qe = _Decimal(10) ** (-new_scale)
return BigDecimal(self._dec.quantize(qe))
py_mode = self._round_map.get(rounding_mode, _DEC_ROUND_HALF_UP)
qe = _Decimal(10) ** (-new_scale)
return BigDecimal(self._dec.quantize(qe, rounding=py_mode))
def ulp(self):
exponent = self._dec.as_tuple().exponent
return BigDecimal(_Decimal(10) ** exponent)
def unscaledValue(self):
t = self._dec.as_tuple()
digits = t.digits
val = int("".join(str(d) for d in digits))
return BigInteger(-val if t.sign else val)
def byteValueExact(self):
val = self.intValueExact()
if val < -128 or val > 127:
raise ArithmeticError("Overflow")
return val
def shortValueExact(self):
val = self.intValueExact()
if val < -32768 or val > 32767:
raise ArithmeticError("Overflow")
return val
def intValueExact(self):
if self._dec != int(self._dec):
raise ArithmeticError("Rounding necessary")
return int(self._dec)
def longValueExact(self):
if self._dec != int(self._dec):
raise ArithmeticError("Rounding necessary")
return int(self._dec)
def floatValue(self):
return float(self._dec)
def doubleValue(self):
return float(self._dec)
def intValue(self):
return int(self._dec)
def longValue(self):
return int(self._dec)
def toString(self):
return str(self._dec)
def toEngineeringString(self):
return format(self._dec, "e")
def toPlainString(self):
return format(self._dec, "f")
def compareTo(self, other):
if isinstance(other, BigDecimal):
return (self._dec > other._dec) - (self._dec < other._dec)
return -1
def equals(self, other):
if isinstance(other, BigDecimal):
return self._dec == other._dec
return False
def hashCode(self):
return hash(self._dec) & 0x7FFFFFFF
def min(self, other):
return BigDecimal(min(self._dec, other._dec if isinstance(other, BigDecimal) else _Decimal(str(other))))
def max(self, other):
return BigDecimal(max(self._dec, other._dec if isinstance(other, BigDecimal) else _Decimal(str(other))))
def __str__(self):
return str(self._dec)
def __int__(self):
return int(self._dec)
def __float__(self):
return float(self._dec)
def __neg__(self):
return self.negate()
def __abs__(self):
return self.abs()
def __add__(self, other):
return self.add(other)
def __sub__(self, other):
return self.subtract(other)
def __mul__(self, other):
return self.multiply(other)
def __truediv__(self, other):
return self.divide(other)
def __mod__(self, other):
return self.remainder(other)
def __pow__(self, other):
return self.pow(other)
BigDecimal.ZERO = BigDecimal(0)
BigDecimal.ONE = BigDecimal(1)
BigDecimal.TEN = BigDecimal(10)