显然,您的算术错误并没有立即清楚。让我把它拼出来。
假设一个 double 有两个部分,大部分和小部分,每个部分的精度大约为 32 位。(这并不完全是双打的工作方式,但它可以满足我们的目的。)
浮子只有一个部分。
想象一下,我们一次处理 32 位,但将所有内容保持为双精度:
double divisor = whatever;
double dividend = dividendbig + dividendlittle;
double bigquotient = dividendbig / divisor;
什么是大商?是双倍的。所以它有两个部分。bigquotient 等于 bigquotientbig + bigquotientlittle。继续:
double littlequotient = dividendlittle / divisor;
同样,littlequotient 是 littlequotientbig + littlequotientlittle。现在我们添加商:
double quotient = bigquotient + littlequotient;
我们如何计算?商有两个部分。quotientbig 将设置为 bigquotientbig。quotientlittle 将设置为 bigquotientlittle + littlequotientbig。littlequotientlittle 被丢弃。
现在假设您在浮动中执行此操作。你有:
float f1 = dividendbig;
float f2 = dividendlittle;
float r1 = f1 / divisor;
好的,r1 是什么?这是一个浮子。所以它只有一个部分。r1 是 bigquotientbig。
float r2 = f2 / divisor;
什么是r2?这是一个浮子。所以它只有一个部分。r2 是 littlequotientbig。
double result = (double)r1 + (double)r2;
你把它们加在一起,你得到 bigquotientbig + littlequotientbig。 bigquotientlittle怎么了? 您已经失去了 32 位的精度,因此您在此过程中得到 32 位的不准确性也就不足为奇了。 您根本没有提出在 32 位中逼近 64 位算术的正确算法。
为了计算(big + little)/divisor
,你不能简单地做(big / divisor) + (little / divisor)
。当您在每个除法 期间四舍五入时,该代数规则不适用!
现在清楚了吗?