4 ms·
It is not at all the same situation as with floating point numbers. 1. It does not use a predetermined finite set of rational numbers. It uses a bigint numerat
by saithound 7y ago
It is not at all the same situation as with floating point numbers.
1. It does not use a predetermined finite set of rational numbers. It uses a bigint numerator and a 64-bit denominator.
2. Even the case of bounded numerator and bounded denominator would preserve more of the nice mathematical properties of rational arithmetic than IEEE 754 floating-point arithmetic does (e.g. the associativity of addition).
3. While the latter could be implemented in hardware, it is not implemented in hardware. The defaults for literals prefer the choice that is implemented in hardware, IEEE 754 floating-point. This is a premature optimization.
- jcranmer 7y ago> 2. Even the case of bounded numerator and bounded denominator would preserve more of the nice mathematical properties of rational arithmetic than IEEE 754 floating-point arithmetic does (e.g. the associativity of addition). It does not preserve associativity of addition. If a = MAX_INT/1, b = 1/1, c = -1/1, then a + b is Infinity, and (a + b) + c is therefore also Infinity, while b + c is 0, so a + (b + c) is MAX_INT/1.
- enriquto 7y agoEven if you allow bigint numerators, addition is still not associative. You can similarly build an example 1/(M-1) - 1/M ...
- saithound 7y ago> It does not preserve associativity of addition. It does, if you use the mathematically natural addition operation (see my reply to enriquto). In the example above, the result is MAX_INT/1 in both cases.
- jcranmer 7y agoAn addition operator where adding two positive numbers results in a negative number can hardly be called "the mathematically natural" variant. Saturation arithmetic (which is the norm for floating point, and even most fixed point) is pretty obviously not associative. Also, it's not clear to me that your proposed wraparound addition operator is actually fully associative in all possible cases of overflow.
- saithound 7y ago> Also, it's not clear to me that your proposed wraparound addition operator is actually fully associative in all possible cases of overflow. Proof sketch: write out (an/ad + (bn/bd) + cn/cd)) and ((an/ad + bn/bd) + cn/cd) symbolically, and apply the fact that twos complement arithmetic is associative, commutative and distributive in all possible cases of overflow. > An addition operator where adding two positive numbers results in a negative number can hardly be called "the mathematically natural" variant. It's exactly how integer arithmetic works on every CPU designed after 1980, to general satisfaction. In any case, it's mathematically natural because it's exactly how you would construct the field of fractions of an integral domain.
- enriquto 7y ago> write out (an/ad + (bn/bd) + cn/cd)) and ((an/ad + bn/bd) + cn/cd) symbolically, and apply the fact that twos complement arithmetic is associative, commutative and distributive in all possible cases of overflow. I doubt that raku/perl6 uses these rules for rational arithmetic. It would be highly unintuitive to sum two rational numbers close to 0.5 and obtain a negative number. Do you have any reference for raku arithmetic rules? I cannot seem to find them.
- dragonwriter 7y agoRaku Rat falls through to floats if the denominator overflows, and has arbitrary precision numerators, it does not use twos-complement math for normal operations in any way exposed to the user, AFAIK. Most other systems (including Scheme) that I've seen that use rational representation by default use arbitrary precision for both numerator and denominator, so don't have this concern.
- dnautics 7y agoYour proof fails for the odd man out negative integer value.
- saithound 7y ago
- enriquto 7y ago> 1. It does not use a predetermined finite set of rational numbers. It uses a bigint numerator and a 64-bit denominator. This is rather ugly for it is not closed by inversion. > 2. Even the case of bounded numerator and bounded denominator would preserve more of the nice mathematical properties of rational arithmetic than IEEE 754 floating-point arithmetic does (e.g. the associativity of addition). I do not see how this can possibly be the case. How do you define rational arithmetic with bounded denominators so that addition is associative? > 3. While the latter could be implemented in hardware, it is not implemented in hardware. The defaults for literals prefer the choice that is implemented in hardware, IEEE 754 floating-point. This is a premature optimization. Alright, but this view is rather subjective, and only valid if you find rational arithmetic more natural than floating point (which many people do not). Regardless of efficiency, using rational arithmetic with bounded integers in numerical computing would be extremely unnatural to most analysts, they would always need to "normalize" the computations so that all the numbers do not become too small, and a lot of ugly tricks that are not needed in floating point. Besides some trivial decimal arithmetic (that can be easily implemented in fixed point for the common use case of counting money), I do not really see the point of the rational representation with bounded ints. Of course, when the denominator is allowed to be a bigint, this is very useful in math, but you'll agree this is a completely different context.
- saithound 7y ago> I do not see how this can possibly be the case. How do you define rational arithmetic with bounded denominators so that addition is associative? There's only one mathematically natural choiceIn the case of bounded numerator and bounded denominator. You simply define (an/ad) + (bn/bd) = (bd × an + ad × bn) / (bd × ad) where the + on the right hand side is ordinary twos complement addition (and the equality test for an/ad and bn/bd is ad × bn == bd × an, which also naturally accounts for the zero-denominator-due-to-zero-divisors cases; alternatively, you can put everything in lowest terms, but there's no point). > Regardless of efficiency, using rational arithmetic with bounded integers in numerical computing would be extremely unnatural to most analysts Floating-point was invented by numerical analysts for numerical analysts. No wonder they find it most natural. The overwhelming majority software developers are not numerical analysts, and most programming languages do not target numerical analysts. Nobody says that numerical analysts should not use floats (except maybe the unum guy), we're arguing about defaults in languages that explicitly do not have numerical analysts among their core target audience.