Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 哪种方法更准确?_C#_Algorithm_Precision_Double Precision_Numerical Computing - Fatal编程技术网

C# 哪种方法更准确?

C# 哪种方法更准确?,c#,algorithm,precision,double-precision,numerical-computing,C#,Algorithm,Precision,Double Precision,Numerical Computing,我需要将一个数值范围划分为一些长度相同的段。但我无法决定哪种方法更准确。例如: double r1 = 100.0, r2 = 1000.0, r = r2 - r1; int n = 30; double[] position = new double[n]; for (int i = 0; i < n; i++) { position[i] = r1 + (double)i / n * r; // position[i] = r1 + i * r / n; } 两者都

我需要将一个数值范围划分为一些长度相同的段。但我无法决定哪种方法更准确。例如:

double r1 = 100.0, r2 = 1000.0, r = r2 - r1;
int n = 30;
double[] position = new double[n];
for (int i = 0; i < n; i++)
{
    position[i] = r1 + (double)i / n * r;
    // position[i] = r1 + i * r / n;
}

两者都不是特别快,因为编译器或JIT进程可能会为了提高效率而对操作进行重新排序。

也许我误解了您的要求,但为什么要在循环中进行除法/乘法呢?也许这会得到同样的结果:

decimal r1 = 100.0m, r2 = 1000.0m, r = r2 - r1;
int n = 30;
decimal[] position = new double[n];

decimal diff = r / n;
decimal current = r1;

for (int i = 0; i < n; i++)
{
    position[i] = current;
    current += diff;
}
十进制r1=100.0m,r2=1000.0m,r=r2-r1;
int n=30;
十进制[]位置=新的双精度[n];
十进制差值=r/n;
十进制电流=r1;
对于(int i=0;i
免责声明:我将作为示例给出的所有数字都不准确,但显示了幕后发生的事情的原理

让我们来看两个案例:

(1)
int1=1000,int2=3,double=3.0
第一个方法将为您提供:
(1000.0/3)*3==333.33333*3.0==999.999…

而第二个将给出
(1000*3.0)/3==3000/3==1000

在这种情况下-第二种方法更准确

(2)
int1=2,int2=2,double=double.MAX\u值

第一个将产生
(2.0/2)*Double.MAX\u值==1*Double.MAX\u值==Double.MAX\u值

虽然第二个将给出
(2*Double.MAX_VALUE)/2
,这将导致(在Java中)无限大,但我不确定双重标准在这种情况下说了什么,如果它可能溢出或总是无限大,但这确实是一个问题。
因此,在本例中-第一种方法更准确

如果
整数
s是
s,或者
双精度
浮点
,事情可能会变得更复杂,因为存在不能用
双精度
s表示的长值,因此在这种情况下,大的
双精度
值可能会丢失,在任何情况下,大的
double
值都不太准确

结论:哪个更好是领域特定的。在某些情况下,第一种方法应该更好,而在某些情况下,第一种方法应该更好。它实际上取决于
int1
int2
double
的值。

然而,对于双精度运算,一般的经验法则是尽可能地减少计算量(不要创建巨大的数字,然后再将其减少,尽可能地保持小)。这个问题被称为。

这是非常正确的。在做这些决定之前,你应该检查NGen'd二进制的反汇编。你确定乘法是可换的吗?就像这篇文章中@Ralu对两个被乘数的解释一样,只有它是可换的。如果有更多的条款,我会同意。OP问的是准确性,而不是speed@TomSirgedas你说得对。我想说的是准确性和速度,但当我意识到我需要纠正我的答案时,哈比卜已经回答了这个问题。我再次成为自己打字速度的牺牲品。这可能会导致错误。因为
diff
是不准确的,小的偏差可能加起来就是一个大错误。嗯,我不太确定(也许我也不太清楚你的需求),你能给出一些示例值吗?或者你会得到一个比另一个大很多的例子?@EFanZh:我仍然不明白我的代码会给你留下什么“大错误”。您可以为我的代码指定哪些会导致准确性问题的输入值?考虑到
r/n
并不完全是“r/n”。你可以试试这个:`double a=1000.0;int n=10000;双t=a/n,和=0;对于(inti=0;ir1=100.0;r2=1000.0;n=10000与我的代码一起,得到了一个
diff=0.09
,最终总数为
1000.00000000011
,显示了一个小错误。但是,如果我使用
十进制
(这是为了避免浮点舍入错误)而不是“double”,那么我的最终总数是1000.0-正好正确。。。这有用吗?(更新代码)在我看来,它应该是平等的。你为什么不试试看有没有区别?这是个很好的问题。我相信会有区别,而且它取决于域(double、int1和int2的范围)。这里的关键词是丢失有效数字。@amit你能回答我的问题让我接受吗?@EFanZh:不幸的是,我不确定在每种情况下哪一个更好。这将只是部分答案。你还想要吗?我认为你应该悬赏这部电影,也许会吸引更多的观众,得到比原先提供的错误答案更好的答案。@amit如果你处于同样的情况,你会怎么做?为什么?如果有合理的理由,我会接受的。在登记VS后不得不移除我的
decimal r1 = 100.0m, r2 = 1000.0m, r = r2 - r1;
int n = 30;
decimal[] position = new double[n];

decimal diff = r / n;
decimal current = r1;

for (int i = 0; i < n; i++)
{
    position[i] = current;
    current += diff;
}