簡體   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