繁体   English   中英

浮动到双重转换 - 单元测试中的最佳断言?

[英]Float to Double conversion - Best assertion in a unit test?

鉴于这些陈述

float f = 7.1f;
double d = f;

我们可以在单元测试中断言d?


例如,这不起作用:

Console.WriteLine(d == 7.1d); // false
Console.WriteLine(d < 7.1d + float.Epsilon); // true by luck
Console.WriteLine(d > 7.1d - float.Epsilon); // false (less luck)

我到目前为止找到的最好的方法是将值转换回来:

float f2 = (float)d;
Console.WriteLine(f2 == f); // true

这与粗野的说法相同

Console.WriteLine(d == 7.1f); // 7.1f implicitly converted to double as above

这个问题一般不是关于double和float精度的,而是关于单元测试如何最好地描述d的限制的实用问题。 在我的例子中,d是由轻量代码生成生成的代码中发生的转换的结果。 在测试这个代码生成时,我必须对这个函数的结果做出断言,这最终归结为上面的简单问题。

你的“最佳方式”是断言你生成的代码返回的内容是float的误差范围7.1 这可能是你要检查的,在这种情况下,继续。

另一方面,您可能希望声明生成的代码特别返回将7.1f转换为double的结果,在这种情况下,您可以执行以下操作:

Console.WriteLine(d == (double)f);

这是更严格的 - 您的测试断言d在一个小范围内,而上述测试断言d是一个特定值。

这真的取决于你将使用什么d 如果事情出现问题,如果它不是确切的值,请测试确切的值,但如果可以在值的float范围内,请检查float

为了比较两个浮点值ibm sugest来测试abs(a/b - 1) < epsilon

msnd指出,当实例的值为零时, Epsilon属性反映了数值运算或比较中最重要的最小正值。

实际上你应该检查一下

Math.Abs(d/(double)f) - 1) < float.Epsilon)

(float) d == f

另一个答案建议d == (double) f ,但这是无用的测试,因为(double) f执行与d = f隐式执行的相同转换。 所以这个断言唯一可以测试的是实现的某些方面是否被破坏(例如,编译器错误地以不同的方式实现了其中一个转换),一些外部机制在赋值和之间改变了df 。断言或源代码被破坏,因此d既不是double也不是float也不是任何能够精确保存f值或者没有执行赋值d = f

通常,我们期望没有浮点误差,因为在浮点的每个正常实现中,从较窄的精度到相同基数的更宽精度的转换没有错误,因为更宽的精度可以表示每个值,更窄的精度可以。 在不常见的情况下,较宽的浮点格式可能具有较小的指数范围。 只有在这种情况下,或者在反常定义的浮点格式中,转换为更宽的格式才会导致值的变化。 在这些情况下,执行相同的转换不会检测到更改。

相反,我们从更宽的格式转换回更窄的格式。 如果df不同,则此转换有可能检测到错误。 例如,假设f包含0x1p-1000,但由于某种原因,这在d的格式中是不可表示的,因此它被舍入为零。 然后(float) d == f求值为(float) 0 == 0x1p-1000 ,然后为0 == 0x1p-1000 ,然后为false 另外,这种测试可以检测相同的错误,其他建议:一个破碎实施方式中,变更df ,一个不正确的类型的d ,而且缺少分配d = f

除此之外,你会在这里用断言检测到什么错误?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM