關于數據精确問題(20分)

  • 主题发起人 主题发起人 zhangjensy
  • 开始时间 开始时间
Z

zhangjensy

Unregistered / Unconfirmed
GUEST, unregistred user!
在DELPHI代碼中計算A+B=C+D<br>我們自己計算時A+B和C+D的結果相等,但不知為什麼當我把它放在一個條件語句中時,如<br>if A+B&lt;&gt;C+D then messagebox('不相等!');<br>由于A,B和C,D都是字段值,但不知為什麼有時就相等,有時就不相等!但前提是我們看到和手工計算都相等!<br>再例如:A=89.45,B=23.34,C=78.12,D=34.67,其實這里A+B和C+D相等,但如果<br>if A+B&lt;&gt;C+D then messagebox('不相等!');就會執行messagebox('不相等!');!<br>如果A,B,C,D換成其它數據時,可能又不會執行這條語句messagebox('不相等!');!<br><br>不知有什麼辦法能使兩邊精度一樣!
 
你的A,B,C三个变量是什么类型的?浮点数是相对精确的 ,只有整形才是绝对精确,对于浮点不能简单的用=/&lt;&gt;来比对,需要用CompareValue函数.
 
A,B,C是DOUBLE,具體如何操作?<br>這樣好象不是很精确!
 
Double当然是不精确的.需要用CompareValue<br>Returns the relationship between two numeric values.<br><br>Unit<br><br>Math<br><br>Category<br><br>Comparison routines<br><br>Delphi syntax:<br><br>function CompareValue(const A, B: Integer): TValueRelationship; overload;<br>function CompareValue(const A, B: Int64): TValueRelationship; overload;<br>function CompareValue(const A, B: Single; Epsilon: Single = 0): TValueRelationship; overload;<br>function CompareValue(const A, B: Double; Epsilon: Double = 0): TValueRelationship; overload;<br>function CompareValue(const A, B: Extended; Epsilon: Extended = 0): TValueRelationship; overload;<br><br>C++ syntax:<br><br>extern PACKAGE TValueRelationship __fastcall CompareValue(const int A, const int B);<br>extern PACKAGE TValueRelationship __fastcall CompareValue(const __int64 A, const __int64 B);<br>extern PACKAGE TValueRelationship __fastcall CompareValue(const float A, const float B, float Epsilon = 0);<br>extern PACKAGE TValueRelationship __fastcall CompareValue(const double A, const double B, <br>double Epsilon = 0);<br><br>extern PACKAGE TValueRelationship __fastcall CompareValue(const Extended A, const Extended<br> B, Extended Epsilon =0);<br><br>Description<br><br>Call CompareValue to determine the relationship between two numeric values. When comparing floating-point values, CompareValue lets you specify a maximum difference to use when comparing values, so that they are considered the same if they are within that amount.<br><br>A and B are the values to compare.<br><br>Epsilon is the maximum amount by which A and B can differ and still be considered the same value.<br><br>CompareValue returns <br><br>LessThanValue if A is less than B (by more than Epsilon if A and B are floating-point numbers).<br> EqualsValue if A is equivalent to B (the same, or within Epsilon if A and B are floating-point numbers).<br> GreaterThanValue if A is larger than B (by more than Epsilon if A and B are floating-point numbers).
 
我的數據只要數确2位小數就可,Epsilon這個如何定義?
 
Example code : Comparing floating point numbers <br>var<br> &nbsp;A : Single;<br> &nbsp;B : Single;<br> &nbsp;C : Single;<br><br>begin<br> &nbsp;A := 23.0;<br> &nbsp;B := 23.0;<br> &nbsp;C := 23.1;<br><br> &nbsp;// Compare 2 equal floats<br> &nbsp;case CompareValue(A, B) of<br> &nbsp; &nbsp;LessThanValue &nbsp; &nbsp;: ShowMessage('A &lt; B');<br> &nbsp; &nbsp;EqualsValue &nbsp; &nbsp; &nbsp;: ShowMessage('A = B');<br> &nbsp; &nbsp;GreaterThanValue : ShowMessage('A &gt; B');<br> &nbsp;end;<br><br> &nbsp;// Compare 2 unequal floats<br> &nbsp;case CompareValue(A, C) of<br> &nbsp; &nbsp;LessThanValue &nbsp; &nbsp;: ShowMessage('A &lt; C');<br> &nbsp; &nbsp;EqualsValue &nbsp; &nbsp; &nbsp;: ShowMessage('A = C');<br> &nbsp; &nbsp;GreaterThanValue : ShowMessage('A &gt; C');<br> &nbsp;end;<br><br> &nbsp;// Compare 2 unequal floats - but allow for a difference of up to +/- 0.2<br> &nbsp;case CompareValue(A, C, 0.2) of<br> &nbsp; &nbsp;LessThanValue &nbsp; &nbsp;: ShowMessage('A &lt; C');<br> &nbsp; &nbsp;EqualsValue &nbsp; &nbsp; &nbsp;: ShowMessage('A = C');<br> &nbsp; &nbsp;GreaterThanValue : ShowMessage('A &gt; C');<br> &nbsp;end;<br>end;
 
如果编译的时候提示LessThanValue/EqualsValue/GreaterThanValue标识符不存在的话,你需要引用types单元.
 
你用numeric字段类型就不会有这个问题了,如两位小数可以这样numeric(18,2)
 
djrj:<br>你說的情況不行!<br>我的程序全是numeric(18,2) <br>有更好的辦法?
 
我的答案不能满足要求?还是楼主看不懂那段英文?
 
浮点数比较时,可以比较双方的差异到一个足够小的小数,即可认为相等。
 
if ((qsettlementdetail.FieldByName('invamount').AsFloat+qsettlementdetail.FieldByName('applyamount').AsFloat)&lt;&gt;qpublicsave.FieldByName('invamount').AsFloat) or ((qsettlementdetail.FieldByName('fbalance').AsFloat+qsettlementdetail.FieldByName('applyfamount').AsFloat)&lt;&gt;qpublicsave.FieldByName('fbalance').AsFloat) then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;MessageBox(GetActiveWindow(), PChar(qsettlementdetail.FieldByName('glcode').AsString+' Settlement Have Changed!'), PChar('Tungfai Group Ltd---Account System'), MB_ICONERROR + MB_OK + MB_SYSTEMMODAL);<br> &nbsp; &nbsp; &nbsp; &nbsp;abort;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br>其中<br>(qsettlementdetail.FieldByName('invamount').AsFloat+qsettlementdetail.FieldByName('applyamount').AsFloat)&lt;&gt;qpublicsave.FieldByName('invamount').AsFloat)<br>和<br>(qsettlementdetail.FieldByName('fbalance').AsFloat+qsettlementdetail.FieldByName('applyfamount').AsFloat)&lt;&gt;qpublicsave.FieldByName('fbalance').AsFloat<br>在我們人工計算是相等,但不知為什麼有時明明相等的東西卻提示不等
 
为什么不用 zqw0117 的方法呢?<br>if (CompareValue(qsettlementdetail.FieldByName('invamount').AsFloat + qsettlementdetail.FieldByName('applyamount').AsFloat, qpublicsave.FieldByName('invamount').AsFloat)&lt;&gt;EqualsValue) or<br> &nbsp; &nbsp; (CompareValue(qsettlementdetail.FieldByName('fbalance').AsFloat + qsettlementdetail.FieldByName('applyfamount').AsFloat, qpublicsave.FieldByName('fbalance').AsFloat)&lt;&gt;EqualsValue)<br> &nbsp;then<br> &nbsp;begin<br> &nbsp; &nbsp;.......<br> &nbsp;end;
 
我的程序中有C,B兩個變量.<br>當電腦計算C-B=A之后,我再放入語句中<br>if C=A+B then messagebox('ok');<br>但當C和B換成不同的變量時,有時顯示不相等,有顯示相等!<br>我想問一下這樣只用CompareValue(C,A+B)這樣行不行?要不要加參數?
 
限制一下精度,如小数点后两位:<br>uses math;<br>if Roundto(A+B,-2)&lt;&gt;RoundTo(C+D,-2) then <br> &nbsp;messagebox('不相等!');
 
浮点数的比较不应该用精确的=来判断<br>可以比较两者的差值,看是否小于一个指定精度就好了<br>如Abs(A-B)&lt;0.0001
 
后退
顶部