The solution to "Error handling"...
H. S. Teoh
hsteoh at qfbox.info
Sun Jul 5 00:29:02 UTC 2026
On Sat, Jul 04, 2026 at 04:55:22PM -0700, Walter Bright via Digitalmars-d wrote:
> Of course. The issue is really that floating point is the best we can
> do when attempting to represent irrational numbers. We cannot even
> represent them on paper, other than as symbols like pi.
Mostly, but not 100% true. Turns out, it *is* possible to represent
certain classes of irrationals losslessly using only integers. There is
a series of theorems in algebra to the effect that algebraic numbers of
degree N can be represented by a N-dimensional vector of rationals (or
equivalently, an (2N)-dimensional vector of integers), closed under
field operations. Thus, it is actually possible to perform (exact!)
arithmetic involving algebraic numbers using only integer arithmetic.
The caveat is that the coefficients of these vectors may be very large
-- in general, when multiplying or dividing algebraic numbers, the
coefficients may grow in number of digits by up to |x|*N, where |x| is
the number of digits of the corresponding coefficient in the operands.
If fixed sized integer coefficients are used, this quickly leads to
integer overflow. So for practical applications this scheme is feasible
only for small N.
In particular, it works quite well for N=2, i.e., for numbers of the
form (x + y*√r) for rational x, y and fixed r. (When r is not fixed,
multiplying two numbers may increase N to 4, with the accompanying
issues with integer overflow.) I have a proof of concept here:
https://github.com/quickfur/qrat
With this little library, I can perform exact arithmetic of numbers of
the form (x + y*√r). I have used this for non-trivial computations,
e.g., to compute exact coordinates for 4-dimensional polytopes in the
field Q(√5).
So it's not entirely true that floating point is inevitable when dealing
with irrationals. If you only need to deal with irrationals of the
above form, it's entirely possible to completely avoid floating-point,
and get exact results for your computations.
The QRat library can also be used with BigInt coefficients, which
completely avoid the integer overflow problem. In principle, you can
perform exact arithmetic with algebraic numbers of degree N using BigInt
coefficients, without ever touching floating-point at all!
[...]
> The bottom line is default 0.0 initialization hides bugs, and NaN
> exposes bugs. I prefer the latter.
Your argument only applies to *modifying* existing *C* code that fails
to initialize float variables and assuming 0.0 is valid initialization.
For new code, written in D which initializes by default, your argument
doesn't apply. New code is written to work with whatever default value
the language imposes on the type, so whether it's NaN or 0.0 doesn't
actually change anything.
For code ported from C, yes defaulting to NaN will catch bugs. But if
you're porting from C, you shouldn't be copy-n-pasting code blindly
without review to begin with.
Code that performs integer calculation also suffers from the same
problem if you fail to initial your integer to the right value, and got
0 instead. You might as well say we should initialize ints to -INTMAX
so that if your result suddenly comes out as an unusually large number
where you expect a small one, you'll know if you have a bug.
T
--
Creativity is not an excuse for sloppiness.
More information about the Digitalmars-d
mailing list