delphi – Invalid floating point operation calling Trunc() – Stack Overflow
Posted by jpluimers on 2021/03/18
I bumped into [WayBack] delphi – Invalid floating point operation calling Trunc() – Stack Overflow, while searching for what might have tests like these fail:
TValueRecordTests.Int64_Through_Value_Container_via_Currency_Intermediate_Is_Identity_Operation(9223372036854775807) = 9223372036854775807 EInvalidOp with message 'Invalid floating point operation'
In the end, it reproduced with a much more simple test case class of which the first three fail (EInvalidOp with message 'Invalid floating point operation'
), but the last three succeed.
Lesson learned:
High(Int64)
stored inCurrency
orDouble
, will notTrunc
back to their original value.Low(Int64)
stored inCurrency
will notTrunc
back to their original value.- Testing boundary conditions is nice, but be sure what your boundary conditions are in the first place.
unit TruncBoundariesTestsUnit; interface uses TestFramework; type TTruncBoundariesTests = class(TTestCase) published procedure Trunc_Currency_High_Int64_stays_identical(); procedure Trunc_Currency_Low_Int64_stays_identical(); procedure Trunc_Double_High_Int64_stays_identical(); procedure Trunc_Double_Low_Int64_stays_identical(); procedure Trunc_Extended_High_Int64_stays_identical(); procedure Trunc_Extended_Low_Int64_stays_identical(); end; implementation procedure TTruncBoundariesTests.Trunc_Currency_High_Int64_stays_identical(); var Actual: Int64; Expected: Int64; Intermediate: Currency; begin Expected := High(Int64); Intermediate := Expected; Actual := Trunc(Intermediate); // EInvalidOp with message 'Invalid floating point operation' CheckEquals(Expected, Actual); end; procedure TTruncBoundariesTests.Trunc_Currency_Low_Int64_stays_identical(); var Actual: Int64; Expected: Int64; Intermediate: Currency; begin Expected := Low(Int64); Intermediate := Expected; Actual := Trunc(Intermediate); // EInvalidOp with message 'Invalid floating point operation' CheckEquals(Expected, Actual); end; procedure TTruncBoundariesTests.Trunc_Double_High_Int64_stays_identical(); var Actual: Int64; Expected: Int64; Intermediate: Double; begin Expected := High(Int64); Intermediate := Expected; Actual := Trunc(Intermediate); // EInvalidOp with message 'Invalid floating point operation' CheckEquals(Expected, Actual); end; procedure TTruncBoundariesTests.Trunc_Double_Low_Int64_stays_identical(); var Actual: Int64; Expected: Int64; Intermediate: Double; begin Expected := Low(Int64); Intermediate := Expected; Actual := Trunc(Intermediate); CheckEquals(Expected, Actual); end; procedure TTruncBoundariesTests.Trunc_Extended_High_Int64_stays_identical(); var Actual: Int64; Expected: Int64; Intermediate: Extended; begin Expected := High(Int64); Intermediate := Expected; Actual := Trunc(Intermediate); CheckEquals(Expected, Actual); end; procedure TTruncBoundariesTests.Trunc_Extended_Low_Int64_stays_identical(); var Actual: Int64; Expected: Int64; Intermediate: Extended; begin Expected := Low(Int64); Intermediate := Expected; Actual := Trunc(Intermediate); CheckEquals(Expected, Actual); end; end.
–jeroen
Leave a Reply