Thread overview
Arbitrary precision decimal numbers
Aug 05
frame
Aug 05
frame
Aug 06
Dom Disc
Aug 06
Dom Disc
Aug 06
Sergey
Aug 11
Tejas
August 04

Is there any implementation in phobos of something similar to BigInt but for non-integers as well? If there isn't is there a dub package that does this, and if so, which one?

August 05

On Thursday, 4 August 2022 at 13:01:30 UTC, Ruby The Roobster wrote:

>

Is there any implementation in phobos of something similar to BigInt but for non-integers as well? If there isn't is there a dub package that does this, and if so, which one?

We have this:

https://code.dlang.org/search?q=decimal

I end up using BigInt instead on a custom wrapper that stores the precision hint. To calculate with any number, it need to convert each value to the same base (eg. storing 10.234 simply results in a BigInt with value 10234 and the precision hint of 3) and then forward the operation to BigInt.

August 05

On Friday, 5 August 2022 at 14:00:32 UTC, frame wrote:

>

On Thursday, 4 August 2022 at 13:01:30 UTC, Ruby The Roobster wrote:

>

Is there any implementation in phobos of something similar to BigInt but for non-integers as well? If there isn't is there a dub package that does this, and if so, which one?

We have this:

https://code.dlang.org/search?q=decimal

I end up using BigInt instead on a custom wrapper that stores the precision hint. To calculate with any number, it need to convert each value to the same base (eg. storing 10.234 simply results in a BigInt with value 10234 and the precision hint of 3) and then forward the operation to BigInt.

I'm already trying to make one, and I have a similar idea, but I ewant it extended to complex numbers.

Also, what about division and exponentiation. You can't just forward them to BigInt and get a good result, BigInt will just round to an integer for these two.

August 05

On Friday, 5 August 2022 at 14:03:36 UTC, Ruby The Roobster wrote:

>

Also, what about division and exponentiation. You can't just forward them to BigInt and get a good result, BigInt will just round to an integer for these two.

There are divMod() and powmod() for BigInt but I have no idea how precise they really are.

August 05

On Friday, 5 August 2022 at 14:11:10 UTC, frame wrote:

>

On Friday, 5 August 2022 at 14:03:36 UTC, Ruby The Roobster wrote:

>

Also, what about division and exponentiation. You can't just forward them to BigInt and get a good result, BigInt will just round to an integer for these two.

There are divMod() and powmod() for BigInt but I have no idea how precise they really are.

I'm currently working on an arbitrarily precise division algortihm based off of the done-by-hand standard algorithm, but I need to get it to work for complex numbers, which it's just not.

August 06

On Friday, 5 August 2022 at 14:25:39 UTC, Ruby The Roobster wrote:

>

I'm currently working on an arbitrarily precise division algortihm based off of the done-by-hand standard algorithm, but I need to get it to work for complex numbers, which it's just not.

I once did a completely inline implementation of xlcmplx based on an arbitrary precision float (in this context called xlfloat) in C++.
You only need to exchange xlfloat with your floatingpoint type:

class xlcmplx
{
	xlfloat Re, Im;
public:
	friend inline void swap(xlcmplx& a, xlcmplx& b) { swap(a.Re, b.Re); swap(a.Im, b.Im); }

	xlcmplx(const xlfloat& re =0, const xlfloat& im =0) : Re(re), Im(im) { }
	xlcmplx(const xlcmplx& c) : Re(c.Re), Im(c.Im) { }
	// two special "constructors":
	friend inline xlcmplx i(const xlfloat& x =1) { return xlcmplx(0,x); } // make pure imaginary number
	friend inline xlcmplx polar(const xlfloat& arg, const xlfloat& norm =1) { return (!norm || !arg) ? norm : xlcmplx(cos(arg),sin(arg)) *= norm; }

	uint32 Decimal(char* s, uint32 max) const; // string representation

	inline xlcmplx& operator=(const xlcmplx& c) { if(this != &c) Re = c.Re, Im = c.Im; return *this; }
	inline xlcmplx& operator=(const xlfloat& f) { Re = f, Im = 0; return *this; }

	inline xlcmplx& operator+() { return *this; } // dummy operator
	inline xlcmplx operator-() const { return xlcmplx(-Re, -Im); }
	inline xlcmplx& operator+=(const xlcmplx& c) { Re += c.Re; Im += c.Im; return *this; }
	inline xlcmplx& operator+=(const xlfloat& f) { Re += f; return *this; }
	inline xlcmplx& operator-=(const xlcmplx& c) { Re -= c.Re; Im -= c.Im; return *this; }
	inline xlcmplx& operator-=(const xlfloat& f) { Re -= f; return *this; }
	inline xlcmplx& operator*=(const xlcmplx& c) { xlfloat t = Re; t *= c.Re; t -= Im*c.Im; Im *= c.Re; Im += Re*c.Im; Re = t; return *this; }
	inline xlcmplx& operator*=(const xlfloat& f) { Re *= f; Im *= f; return *this; }
	inline xlcmplx& operator/=(const xlcmplx& c) { return *this *= inv(c); }
	inline xlcmplx& operator/=(const xlfloat& f) { Re /= f; Im /= f; return *this; }

	inline bool operator==(const xlcmplx& c) const { return Im == c.Im && Re == c.Re; }
	inline bool operator==(const xlfloat& f) const { return !Im && Re == f; }
	inline bool operator!=(const xlcmplx& c) const { return Im != c.Im || Re != c.Re; }
	inline bool operator!=(const xlfloat& f) const { return !!Im || Re != f; }

	friend inline const xlfloat& real(const xlcmplx& c) { return c.Re; }
	friend inline const xlfloat& imag(const xlcmplx& c) { return c.Im; }
	friend inline xlfloat norm(const xlcmplx& c) { return c.Im ? c.Re ? sqr(quad(c.Re)+quad(c.Im)) : abs(c.Im) : abs(c.Re); }
	friend inline xlfloat arg(const xlcmplx& c) { return atan2(c.Re, c.Im); } // an angle in [0..2*pi[

	friend inline xlcmplx conj(xlcmplx c) { c.Im.neg(); return c; }
	friend inline xlcmplx inv(const xlcmplx& c) { xlfloat t = quad(c.Re); t += quad(c.Im); return conj(c) /= t; }
	friend inline xlcmplx quad(const xlcmplx& c) { return xlcmplx(quad(c.Re)-quad(c.Im),(c.Re*c.Im)<<1); }
	friend inline xlcmplx exp(const xlcmplx& c) { return c.Im ? xlcmplx(cos(c.Im), sin(c.Im)) *= exp(c.Re) : exp(c.Re); }
	friend inline xlcmplx sin(const xlcmplx& c) { return c.Im ? c.Re ? xlcmplx(sin(c.Re)*cosh(c.Im), cos(c.Re)*sinh(c.Im)) : i(sinh(c.Im)) : sin(c.Re); }
	friend inline xlcmplx cos(const xlcmplx& c) { return c.Im ? c.Re ? xlcmplx(cos(c.Re)*cosh(c.Im), sin(c.Re)*sinh(c.Im)) : cosh(c.Im) : cos(c.Re); }
	friend inline xlcmplx ln(const xlcmplx& c) { return xlcmplx(ln(norm(c)), arg(c)); } // main value - multiples of 2*pi*i added are also valid results
};

inline bool operator==(const xlfloat& f, const xlcmplx& c) { return c == f; }
inline bool operator!=(const xlfloat& f, const xlcmplx& c) { return c != f; }

inline xlcmplx operator+(xlcmplx a, const xlcmplx& b) { return a += b; }
inline xlcmplx operator+(xlcmplx a, const xlfloat& b) { return a += b; }
inline xlcmplx operator+(const xlfloat& a, xlcmplx b) { return b += a; }
inline xlcmplx operator-(xlcmplx a, const xlcmplx& b) { return a -= b; }
inline xlcmplx operator-(xlcmplx a, const xlfloat& b) { return a -= b; }
inline xlcmplx operator-(const xlfloat& a, const xlcmplx& b) { return -b += a; }
inline xlcmplx operator*(xlcmplx a, const xlfloat& b) { return a *= b; }
inline xlcmplx operator*(xlcmplx a, const xlcmplx& b) { return a *= b; }
inline xlcmplx operator*(const xlfloat& a, xlcmplx b) { return b *= a; }
inline xlcmplx operator/(xlcmplx a, const xlcmplx& b) { return a /= b; }
inline xlcmplx operator/(xlcmplx a, const xlfloat& b) { return a /= b; }
inline xlcmplx operator/(const xlfloat& a, const xlcmplx& b) { return xlcmplx(a) /= b; }

inline xlcmplx pow(const xlcmplx& c, const int exp) { return polar(arg(c)*exp, pow(norm(c), exp)); }
inline xlcmplx pow(const xlcmplx& c, const xlfloat& exp) { return polar(arg(c)*exp, pow(norm(c), exp)); }
inline xlcmplx log(const xlcmplx& c, const uint32 base = 10) { return ln(c) /= ln(number(base)); }

You can also get the implementation of xlfloat, if you like - but that one is NOT completely inline and much longer :-D

August 06

On Saturday, 6 August 2022 at 11:25:28 UTC, Dom Disc wrote:

>

I once did a completely inline implementation of xlcmplx

Sorry, one function is NOT inline:

>
class xlcmplx
{
	uint32 Decimal(char* s, uint32 max) const; // string representation
}

But you should forget about that, because D has much better methods to create a string. In fact good enough that also this function could have been inline... but in D the whole concept of headers is superfluous, so who cares.

August 06

On Thursday, 4 August 2022 at 13:01:30 UTC, Ruby The Roobster wrote:

>

Is there any implementation in phobos of something similar to BigInt but for non-integers as well? If there isn't is there a dub package that does this, and if so, which one?

Also you could find usefull such projects:

http://mir-algorithm.libmir.org/mir_bignum_decimal.html

https://github.com/huntlabs/hunt-extra/blob/2d286f939193fc0cd55c799906f7657cec502dc8/source/hunt/math/BigDecimal.d

August 10

On Saturday, 6 August 2022 at 13:20:19 UTC, Sergey wrote:

>

On Thursday, 4 August 2022 at 13:01:30 UTC, Ruby The Roobster wrote:

>

Is there any implementation in phobos of something similar to BigInt but for non-integers as well? If there isn't is there a dub package that does this, and if so, which one?

Also you could find usefull such projects:

http://mir-algorithm.libmir.org/mir_bignum_decimal.html

https://github.com/huntlabs/hunt-extra/blob/2d286f939193fc0cd55c799906f7657cec502dc8/source/hunt/math/BigDecimal.d

It doesn't provide for arithmetic operations though, according to the docs.

August 11

On Wednesday, 10 August 2022 at 14:11:04 UTC, Ruby The Roobster wrote:

>

On Saturday, 6 August 2022 at 13:20:19 UTC, Sergey wrote:

>

On Thursday, 4 August 2022 at 13:01:30 UTC, Ruby The Roobster wrote:

>

Is there any implementation in phobos of something similar to BigInt but for non-integers as well? If there isn't is there a dub package that does this, and if so, which one?

Also you could find usefull such projects:

http://mir-algorithm.libmir.org/mir_bignum_decimal.html

https://github.com/huntlabs/hunt-extra/blob/2d286f939193fc0cd55c799906f7657cec502dc8/source/hunt/math/BigDecimal.d

It doesn't provide for arithmetic operations though, according to the docs.

Maybe you'll have better luck with this?

https://code.dlang.org/packages/gmp-d