提问人:Gregory Fenn 提问时间:10/24/2018 更新时间:10/24/2018 访问量:382
在 C# 中复制后是否保证双精度/浮点数相等?[复制]
Is double/float equality guaranteed after copying in C#? [duplicate]
问:
对于一个非常简单的问题,我找不到一个清晰、简单的答案!我将我的问题分为两个版本。
在 C# 中,假设我运行以下命令:
double x = 76239.78362194721;
double y = -3;
y = x; // copied by value, as doubles are literals
//y = y + 1.4; // Version 1 of my question has these commented-out
//x = x + 1.4; // Version 2 of my question has these not commented-out
bool b = (x == y);
布尔值会永远为真吗?也就是说,尽管双打之间的相等度量不准确,但计算机永远不会故意添加噪音吗?b
并且可能取决于我问的问题是版本 1 还是版本 2?(我们可以假设 并且不接近 double 的最大值或最小值,也不接近正负 epsilon)。b
x
y
谢谢! ~格雷格
答:
复制不会造成任何精度损失。y = x;
赋值后,为 true。x == y
由于 和 相等,之后x
y
y = y + 1.4;
x = x + 1.4;
x == y
很可能是真的;然而,正如埃里克·利珀特(Eric Lippert)所指出的那样(见下面的评论),这并不能保证。
始终将双打与所需的精度进行比较:
const double Eps = 1e-10;
if (Math.Abs(x - y) < Eps) {
// x and y are equal enough
} else {
// x and y are not equal
}
当然,如果您只注释掉其中之一,并且会相差大约.它们可能会有所不同。如果两者都非常大(例如),则加法将不起作用,因为它会影响被截断的小数点。 精度为 15-16 位。如果两者都非常小(例如),也是如此,因为这样它们的原始值将丢失,结果将是 。x
y
1.4
1.399999999999999
1.400000000000001
1.0e25
double
1.0e-25
1.4
在 C# 交互窗口中,您可以测试它
> 1e+25 + 1.4 == 1e+25
true
并且
> 1e-25 + 1.4 == 1.4
true
...按值复制,因为双精度是文字
嗯,不完全是。 (C# 别名 )是一种值类型。 是字面意思。标识符中是一个变量(如果是在类型级别声明的,则为字段)。System.Double
double
3.141592654
double
double x;
x
double
但即使你复制......
var p1 = new Person { Name = "John" }; // Where Person is a class.
var p2 = p1;
// Now, p1 and p2 reference the same object. I.e. they have the same value.
...变量的值是按值复制的。不同之处在于,此值是参考值。该值不是 person 对象,而是对它的引用。
p2.Name = "Mark";
现在是真的,但值没有改变。它仍然是相同的参考。引用的对象确实发生了更改。p1.Name == "Mark"
p1
double d1 = 5;
double d2 = d1;
d2 = 77;
d1
还是 5 岁。因为是值类型,所以变量直接包含数字。不涉及参考文献。double
在另一个示例中,引用是通过引用传递的
var p1 = new Person{ Name = "John" };
AssignAnotherPerson(ref p1);
void AssignAnotherPerson(ref Person p)
{
p = new Person{ Name = "Sue" }; // Here p is an alias for p1.
}
调用此方法后,将包含 Sue 人。p1
可以有四种情况:(1) 按值传递的值类型。(2) 通过引用传递的值类型。(3) 按值传递的引用类型。(4) 通过引用传递的引用类型。
评论
double x = 123.45 + 7.89; double y = 123.45; double z = 7.89; bool b = x == y + z;
b
false
x
评论