aleaxit / gmpy

General Multi-Precision arithmetic for Python 2.6+/3+ (GMP, MPIR, MPFR, MPC)
https://gmpy2.readthedocs.io/en/latest/
GNU Lesser General Public License v3.0
516 stars 87 forks source link

Is there an alternative for Decimal? #473

Closed Nov1kov closed 6 months ago

Nov1kov commented 6 months ago

Hello, thank you for great tool.

I want to improve performance with gmpy2 with big numbers. But in some cases, I can't use analog from gmpy2.

from decimal import Decimal
from gmpy2 import mpz
a = -92101
b = 60
int(Decimal(a) // b) # -1535
int(mpz(a) // b) # -1536
int(mpq(a) // b) # -1536
int(mpfr(a) // b) # -1536

Could you please explain more?

  1. What is the best way to convert to Decimal from gmpy2 types? Because directly convert impossible - TypeError: conversion from mpz to Decimal is not supported
  2. What is the nearest way to use gmpy2 instead of "py - Decimal" types?
skirpichev commented 6 months ago

Could you please explain more?

I believe, this is explained in the decimal module documentation. Namely, here:

There are some small differences between arithmetic on Decimal objects and arithmetic
on integers and floats. When the remainder operator % is applied to Decimal objects,
the sign of the result is the sign of the dividend rather than the sign of the divisor:
>>> (-7) % 4
1
>>> Decimal(-7) % Decimal(4)
Decimal('-3')

The integer division operator // behaves analogously, returning the integer part of
the true quotient (truncating towards zero) rather than its floor, so as to preserve
the usual identity x == (x // y) * y + x % y:
>>> -7 // 4
-2
>>> Decimal(-7) // Decimal(4)
Decimal('-1')

mpz_fdiv_q() (used by mpz(a)//b) round down to -oo. The remainder has same sign as the divisor.

What is the best way to convert to Decimal from gmpy2 types?

In general, you could use as_integer_ratio() method to get exact value of mpfr as a fraction.

What is the nearest way to use gmpy2 instead of "py - Decimal" types?

The point of the decimal module is correctly rounded decimal floating point arithmetic. There is no way to use gmpy2 to do same: it offers binary floating point arithmetic.

Nov1kov commented 6 months ago

Thank you, useful answer!

skirpichev commented 6 months ago

@Nov1kov, do you think there is some issue with the gmpy2 code?

Nov1kov commented 6 months ago

No, I think this is not an error, I did not find a similar question or place to ask my question.

I hope this ticket will help others.

skirpichev commented 6 months ago

I did not find a similar question or place to ask my question.

It's fine to do here. Perhaps, "Discussions" forum could be better, but...