From: Maxim Shemanarev (mcseem_at_[hidden])
Date: 2002-08-22 19:15:08


> First of all, I agree with Maxim that a general core-level solution is
> really
> difficult, not only because it is difficult to define consistent semantics
> for it, but also because of backward compatibility.

Not only because of that.

1. Expressions can be very complex and in these cases it's not obvious what
to do, I mean what data types the compiler should use for internal
variables. Twice longer? But why only twice?. I've already gave this
example, what if we have y = x*a*b*c/d; Look, x*a is 64 bits, x*a*b
theoretically should be 96 bits and x*a*b*c is 128 bits! So, it's absolutely
right to lose *intentionally* most significant part of the mul-product on
each step.

2. Remember the division-by-zero issue. On most machines it throws a
hardware exception. But at least on Intel it occures not only when you
divide by zero, but also when the result of the division doesn't fit 32-bit
value! I.e. if you try this (suppose we downgrade everything to 16 bits
unsigned):
mov ax, 60000
umul 50000
udiv 10
You will have the very same zero-divide exception. But if you add the "cwd"
command after "umul" it'll be impossible to have it.

Again, the way all C-compilers treat integer expressions is absolutely
correct!
What I'm talking about is to have only a very special case for only this
expression a*b/c. That's it, thank you for understanding :-)

> template<class N>
> struct algebra_kernel
> {
> template<class T>
> static T muldiv ( T x, T y,T w)
> {
> return static_cast<T>( static_cast<N>(x) * static_cast<N>(y) /
> static_cast<N>(w)) ;
> }
>
> .... so on ...
> } ;

This technique is exactly what I said in the original post. But it will
result in calling internal mul64 and div64 and so, slowing down the
calculations.

McSeem