Thread overview
Arbitrary precision decimal numbers
Aug 04, 2022
Ruby The Roobster
Aug 05, 2022
frame
Aug 05, 2022
Ruby The Roobster
Aug 05, 2022
frame
Aug 05, 2022
Ruby The Roobster
Aug 06, 2022
Dom Disc
Aug 06, 2022
Dom Disc
Aug 06, 2022
Sergey
Aug 10, 2022
Ruby The Roobster
Aug 11, 2022
Tejas
August 04, 2022

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, 2022

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, 2022

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, 2022

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, 2022

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, 2022

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, 2022

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, 2022

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, 2022

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, 2022

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