On Tuesday, 1 October 2013 at 08:02:12 UTC, Joseph Rushton
Wakeling wrote:
On 01/10/13 08:26, ilya-stromberg wrote:
Note that denumerator must be allways positive (> 0).
But numerator can be positive, zero or negative, and can be
bigger than
denumerator.
It means that we can use different types for numerator and
denumerator:
Seems an overcomplication for me, and it doesn't save you from
denominator == 0, so it doesn't get you out of any checks.
It's from a mathematics:
http://ru.wikipedia.org/wiki/%D0%94%D1%80%D0%BE%D0%B1%D1%8C_%28%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0%29
Numerator must be integer (..., -2, -1, 0, 1, 2, ...):
http://en.wikipedia.org/wiki/Integer
Denumerator must be natural number (1, 2, 3, ...):
http://en.wikipedia.org/wiki/Natural_number
Note that english wikipedia says that denumerator is integer not
equal to zero:
http://en.wikipedia.org/wiki/Rational_number
It's interesting: have we got 2 different mathematics, or it's
just mistake in wikipedia? I didn't read any english mathematics
books, but the GMP library agree with me:
"All rational arithmetic functions assume operands have a
canonical form, and canonicalize their result. The canonical from
means that the denominator and the numerator have no common
factors, and that the denominator is positive. Zero has the
unique representation 0/1."
http://gmplib.org/manual/Rational-Number-Functions.html#Rational-Number-Functions
May be you are rigth and store numerator and denumerator type is
too complex, but it have some benefits. For example, we can save
some memory with BigUint type because it doesn't store
unnecessary sign.
We have BigUint in Phobos, but it's private.
Interesting. Any particular reason? (I suppose the nature of
BigInt is that you don't need to worry about signed/unsigned
distinction because there is no range limit.)
I don't know, I just found it in source code:
https://github.com/D-Programming-Language/phobos/blob/master/std/bigint.d
module std.bigint;
private import std.internal.math.biguintcore;
struct BigInt
{
private:
BigUint data; // BigInt adds signed arithmetic to BigUint.
bool sign = false;
//...
}
Also, if we need only positive rationals, we can use unsigned
types for numerator:
Yes, but you can already get that as is by
Rational!(UnsignedTypeOfChoice) :-)