Make sure we pass MPZ mantissa to from_man_exp()

This commit is contained in:
Sergey B Kirpichev
2025-01-29 04:00:25 +03:00
parent 4fb7367100
commit 2550656706
5 changed files with 59 additions and 59 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ class _mpf(mpnumeric):
if len(val) == 4:
val = val[0], MPZ(val[1]), *val[2:]
elif len(val) == 2:
v._mpf_ = from_man_exp(val[0], val[1], prec, rounding)
v._mpf_ = from_man_exp(MPZ(val[0]), val[1], prec, rounding)
return v
else:
raise ValueError
+1 -1
View File
@@ -421,7 +421,7 @@ def mpf_bernoulli(n, prec, rnd=round_fast, plus=False):
# Accurately estimate size of B_m so we can use
# fixed point math without using too much precision
szbm = bernoulli_size(m)
s = 0
s = MPZ(0)
sexp = max(0, szbm) - wp
if m < 6:
a = MPZ_ZERO
+2 -2
View File
@@ -7,7 +7,7 @@ cases are also provided.
import math
from .backend import MPZ_ONE, MPZ_ZERO
from .backend import MPZ, MPZ_ONE, MPZ_ZERO
from .gammazeta import euler_fixed, mpf_euler, mpf_gamma_int
from .libelefun import (agm_fixed, mpf_cos_sin, mpf_exp, mpf_log, mpf_pi,
mpf_sin, mpf_sqrt, pi_fixed)
@@ -653,7 +653,7 @@ def mpf_expint(n, x, prec, rnd=round_fast, gamma=False):
for k in range(1,n-1):
facs[k] = facs[k-1] * k
facs = facs[::-1]
s = facs[0] << wp
s = MPZ(facs[0]) << wp
for k in range(1, n-1):
if k & 1:
s -= facs[k] * t
+4 -4
View File
@@ -243,7 +243,7 @@ def from_int(n, prec=0, rnd=round_fast):
if not prec:
if n in int_cache:
return int_cache[n]
return from_man_exp(n, 0, prec, rnd)
return from_man_exp(MPZ(n), 0, prec, rnd)
def to_man_exp(s, signed=None):
"""Return (man, exp) of a raw mpf. Raise an error if inf/nan."""
@@ -347,7 +347,7 @@ def from_npfloat(x, prec=113, rnd=round_fast):
import numpy as np
if np.isfinite(x):
m, e = np.frexp(x)
return from_man_exp(int(np.ldexp(m, 113)), int(e)-113, prec, rnd)
return from_man_exp(MPZ(np.ldexp(m, 113)), int(e)-113, prec, rnd)
return fnan
def from_Decimal(x, prec=0, rnd=round_fast):
@@ -439,7 +439,7 @@ def to_fixed(s, prec):
def mpf_rand(prec):
"""Return a raw mpf chosen randomly from [0, 1), with prec bits
in the mantissa."""
return from_man_exp(random.getrandbits(prec), -prec, prec, round_floor)
return from_man_exp(MPZ(random.getrandbits(prec)), -prec, prec, round_floor)
def mpf_eq(s, t):
"""Test equality of two raw mpfs. This is simply tuple comparison
@@ -714,7 +714,7 @@ def mpf_sum(xs, prec=0, rnd=round_fast, absolute=False):
With absolute=True, sums the absolute values.
"""
man = 0
man = MPZ(0)
exp = 0
max_extra_prec = prec*2 or 1000000 # XXX
special = None
+51 -51
View File
@@ -3,7 +3,7 @@ Test bit-level integer and mpf operations
"""
from mpmath import eps, fadd, ldexp, mp, mpc, mpf
from mpmath.libmp import (bitcount, fone, from_float, from_man_exp, fzero,
from mpmath.libmp import (MPZ, bitcount, fone, from_float, from_man_exp, fzero,
mpf_add, mpf_neg, mpf_perturb, mpf_sub,
round_ceiling, round_down, round_floor,
round_nearest, round_up, to_float, trailing)
@@ -27,69 +27,69 @@ def test_trailing():
assert trailing(2**100-1) == 0
def test_round_down():
assert from_man_exp(0, -4, 4, round_down)[:3] == (0, 0, 0)
assert from_man_exp(0xf0, -4, 4, round_down)[:3] == (0, 15, 0)
assert from_man_exp(0xf1, -4, 4, round_down)[:3] == (0, 15, 0)
assert from_man_exp(0xff, -4, 4, round_down)[:3] == (0, 15, 0)
assert from_man_exp(-0xf0, -4, 4, round_down)[:3] == (1, 15, 0)
assert from_man_exp(-0xf1, -4, 4, round_down)[:3] == (1, 15, 0)
assert from_man_exp(-0xff, -4, 4, round_down)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(0), -4, 4, round_down)[:3] == (0, 0, 0)
assert from_man_exp(MPZ(0xf0), -4, 4, round_down)[:3] == (0, 15, 0)
assert from_man_exp(MPZ(0xf1), -4, 4, round_down)[:3] == (0, 15, 0)
assert from_man_exp(MPZ(0xff), -4, 4, round_down)[:3] == (0, 15, 0)
assert from_man_exp(MPZ(-0xf0), -4, 4, round_down)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(-0xf1), -4, 4, round_down)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(-0xff), -4, 4, round_down)[:3] == (1, 15, 0)
def test_round_up():
assert from_man_exp(0, -4, 4, round_up)[:3] == (0, 0, 0)
assert from_man_exp(0xf0, -4, 4, round_up)[:3] == (0, 15, 0)
assert from_man_exp(0xf1, -4, 4, round_up)[:3] == (0, 1, 4)
assert from_man_exp(0xff, -4, 4, round_up)[:3] == (0, 1, 4)
assert from_man_exp(-0xf0, -4, 4, round_up)[:3] == (1, 15, 0)
assert from_man_exp(-0xf1, -4, 4, round_up)[:3] == (1, 1, 4)
assert from_man_exp(-0xff, -4, 4, round_up)[:3] == (1, 1, 4)
assert from_man_exp(MPZ(0), -4, 4, round_up)[:3] == (0, 0, 0)
assert from_man_exp(MPZ(0xf0), -4, 4, round_up)[:3] == (0, 15, 0)
assert from_man_exp(MPZ(0xf1), -4, 4, round_up)[:3] == (0, 1, 4)
assert from_man_exp(MPZ(0xff), -4, 4, round_up)[:3] == (0, 1, 4)
assert from_man_exp(MPZ(-0xf0), -4, 4, round_up)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(-0xf1), -4, 4, round_up)[:3] == (1, 1, 4)
assert from_man_exp(MPZ(-0xff), -4, 4, round_up)[:3] == (1, 1, 4)
def test_round_floor():
assert from_man_exp(0, -4, 4, round_floor)[:3] == (0, 0, 0)
assert from_man_exp(0xf0, -4, 4, round_floor)[:3] == (0, 15, 0)
assert from_man_exp(0xf1, -4, 4, round_floor)[:3] == (0, 15, 0)
assert from_man_exp(0xff, -4, 4, round_floor)[:3] == (0, 15, 0)
assert from_man_exp(-0xf0, -4, 4, round_floor)[:3] == (1, 15, 0)
assert from_man_exp(-0xf1, -4, 4, round_floor)[:3] == (1, 1, 4)
assert from_man_exp(-0xff, -4, 4, round_floor)[:3] == (1, 1, 4)
assert from_man_exp(MPZ(0), -4, 4, round_floor)[:3] == (0, 0, 0)
assert from_man_exp(MPZ(0xf0), -4, 4, round_floor)[:3] == (0, 15, 0)
assert from_man_exp(MPZ(0xf1), -4, 4, round_floor)[:3] == (0, 15, 0)
assert from_man_exp(MPZ(0xff), -4, 4, round_floor)[:3] == (0, 15, 0)
assert from_man_exp(MPZ(-0xf0), -4, 4, round_floor)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(-0xf1), -4, 4, round_floor)[:3] == (1, 1, 4)
assert from_man_exp(MPZ(-0xff), -4, 4, round_floor)[:3] == (1, 1, 4)
def test_round_ceiling():
assert from_man_exp(0, -4, 4, round_ceiling)[:3] == (0, 0, 0)
assert from_man_exp(0xf0, -4, 4, round_ceiling)[:3] == (0, 15, 0)
assert from_man_exp(0xf1, -4, 4, round_ceiling)[:3] == (0, 1, 4)
assert from_man_exp(0xff, -4, 4, round_ceiling)[:3] == (0, 1, 4)
assert from_man_exp(-0xf0, -4, 4, round_ceiling)[:3] == (1, 15, 0)
assert from_man_exp(-0xf1, -4, 4, round_ceiling)[:3] == (1, 15, 0)
assert from_man_exp(-0xff, -4, 4, round_ceiling)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(0), -4, 4, round_ceiling)[:3] == (0, 0, 0)
assert from_man_exp(MPZ(0xf0), -4, 4, round_ceiling)[:3] == (0, 15, 0)
assert from_man_exp(MPZ(0xf1), -4, 4, round_ceiling)[:3] == (0, 1, 4)
assert from_man_exp(MPZ(0xff), -4, 4, round_ceiling)[:3] == (0, 1, 4)
assert from_man_exp(MPZ(-0xf0), -4, 4, round_ceiling)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(-0xf1), -4, 4, round_ceiling)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(-0xff), -4, 4, round_ceiling)[:3] == (1, 15, 0)
def test_round_nearest():
assert from_man_exp(0, -4, 4, round_nearest)[:3] == (0, 0, 0)
assert from_man_exp(0xf0, -4, 4, round_nearest)[:3] == (0, 15, 0)
assert from_man_exp(0xf7, -4, 4, round_nearest)[:3] == (0, 15, 0)
assert from_man_exp(0xf8, -4, 4, round_nearest)[:3] == (0, 1, 4) # 1111.1000 -> 10000.0
assert from_man_exp(0xf9, -4, 4, round_nearest)[:3] == (0, 1, 4) # 1111.1001 -> 10000.0
assert from_man_exp(0xe8, -4, 4, round_nearest)[:3] == (0, 7, 1) # 1110.1000 -> 1110.0
assert from_man_exp(0xe9, -4, 4, round_nearest)[:3] == (0, 15, 0) # 1110.1001 -> 1111.0
assert from_man_exp(-0xf0, -4, 4, round_nearest)[:3] == (1, 15, 0)
assert from_man_exp(-0xf7, -4, 4, round_nearest)[:3] == (1, 15, 0)
assert from_man_exp(-0xf8, -4, 4, round_nearest)[:3] == (1, 1, 4)
assert from_man_exp(-0xf9, -4, 4, round_nearest)[:3] == (1, 1, 4)
assert from_man_exp(-0xe8, -4, 4, round_nearest)[:3] == (1, 7, 1)
assert from_man_exp(-0xe9, -4, 4, round_nearest)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(0), -4, 4, round_nearest)[:3] == (0, 0, 0)
assert from_man_exp(MPZ(0xf0), -4, 4, round_nearest)[:3] == (0, 15, 0)
assert from_man_exp(MPZ(0xf7), -4, 4, round_nearest)[:3] == (0, 15, 0)
assert from_man_exp(MPZ(0xf8), -4, 4, round_nearest)[:3] == (0, 1, 4) # 1111.1000 -> 10000.0
assert from_man_exp(MPZ(0xf9), -4, 4, round_nearest)[:3] == (0, 1, 4) # 1111.1001 -> 10000.0
assert from_man_exp(MPZ(0xe8), -4, 4, round_nearest)[:3] == (0, 7, 1) # 1110.1000 -> 1110.0
assert from_man_exp(MPZ(0xe9), -4, 4, round_nearest)[:3] == (0, 15, 0) # 1110.1001 -> 1111.0
assert from_man_exp(MPZ(-0xf0), -4, 4, round_nearest)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(-0xf7), -4, 4, round_nearest)[:3] == (1, 15, 0)
assert from_man_exp(MPZ(-0xf8), -4, 4, round_nearest)[:3] == (1, 1, 4)
assert from_man_exp(MPZ(-0xf9), -4, 4, round_nearest)[:3] == (1, 1, 4)
assert from_man_exp(MPZ(-0xe8), -4, 4, round_nearest)[:3] == (1, 7, 1)
assert from_man_exp(MPZ(-0xe9), -4, 4, round_nearest)[:3] == (1, 15, 0)
def test_rounding_bugs():
# 1 less than power-of-two cases
assert from_man_exp(72057594037927935, -56, 53, round_up) == (0, 1, 0, 1)
assert from_man_exp(73786976294838205979, -65, 53, round_nearest) == (0, 1, 1, 1)
assert from_man_exp(31, 0, 4, round_up) == (0, 1, 5, 1)
assert from_man_exp(-31, 0, 4, round_floor) == (1, 1, 5, 1)
assert from_man_exp(255, 0, 7, round_up) == (0, 1, 8, 1)
assert from_man_exp(-255, 0, 7, round_floor) == (1, 1, 8, 1)
assert from_man_exp(MPZ(72057594037927935), -56, 53, round_up) == (0, 1, 0, 1)
assert from_man_exp(MPZ(73786976294838205979), -65, 53, round_nearest) == (0, 1, 1, 1)
assert from_man_exp(MPZ(31), 0, 4, round_up) == (0, 1, 5, 1)
assert from_man_exp(MPZ(-31), 0, 4, round_floor) == (1, 1, 5, 1)
assert from_man_exp(MPZ(255), 0, 7, round_up) == (0, 1, 8, 1)
assert from_man_exp(MPZ(-255), 0, 7, round_floor) == (1, 1, 8, 1)
def test_rounding_issue_200():
a = from_man_exp(9867,-100)
b = from_man_exp(9867,-200)
c = from_man_exp(-1,0)
a = from_man_exp(MPZ(9867),-100)
b = from_man_exp(MPZ(9867),-200)
c = from_man_exp(MPZ(-1),0)
z = (1, 1023, -10, 10)
assert mpf_add(a, c, 10, 'd') == z
assert mpf_add(b, c, 10, 'd') == z