[xe7.1]
This was functioning on XE6 and previous, I was not paying attention until
I found this problem recently and I am still not understanding what is going
on:
When selecting ranges for reporting I usually do for end date EndOfTheDay(Date)
Then this function gets my Date with no time on it and adds '23:59:59:99'
to it.
FOr example: 31/12/2014 should be added and get one milissecond before the
new year.
However it is turning to 01/01/2015 always.
I have traced to this point on system.dateutils:
function TryEncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond,
AMilliSecond: Word; out AValue: TDateTime): Boolean;
var
LTime: TDateTime;
begin
Result := TryEncodeDate(AYear, AMonth, ADay, AValue);
if Result then
begin
Result := TryEncodeTime(AHour, AMinute, ASecond, AMilliSecond, LTime);
if Result then
if AValue >= 0 then
AValue := AValue + LTime
else
AValue := AValue - LTime
end;
end;
Both results are returning correctly the value for date = 31/12/2014 and
for time = 30/12/1899 23:59:59
Then at this line
AValue := AValue + LTime
it is going to 01/01/2015.
That is weird.
Any ideas?
Eduardo
Eduardo Elias wrote:
> Remy, others,
>
> I have made more tests and there is no CPU problem or hardware.
>
> On the host OS the software is working correct showing the values with correct
> number of decimals
>
> On the VM, from inside IDE or not, it shows a lot of decimals for any number.
>
> There is something that interferes on the way Delphi works with floating
> point, but I cant find what is the reason and that is causing me a lot of
> trouble !
>
> Please, I wonder if someone could give a help!
Maybe fpu 8087 control word (OS dependent)
http://docwiki.embarcadero.com/Libraries/XE7/en/System.Default8087CW
http://docwiki.embarcadero.com/Libraries/XE7/en/System.Get8087CW
http://docwiki.embarcadero.com/Libraries/XE7/en/System.Set8087CW
http://docwiki.embarcadero.com/Libraries/XE7/en/System.Reset8087CW
http://docwiki.embarcadero.com/Libraries/XE7/en/System.Test8087
And generally about fp affecting routines
http://docwiki.embarcadero.com/RADStudio/XE7/en/Floating-Point_Number_Control_Routines
Cheers
--
Tom Brunberg
firstname.lastname@welho.com
Remy, others,
I have made more tests and there is no CPU problem or hardware.
On the host OS the software is working correct showing the values with correct
number of decimals
On the VM, from inside IDE or not, it shows a lot of decimals for any number.
There is something that interferes on the way Delphi works with floating
point, but I cant find what is the reason and that is causing me a lot of
trouble !
Please, I wonder if someone could give a help!
Eduardo
> Eduardo wrote:
>
>> I have created a small example to test this on another computer and
>> for my surprise it worked inside the same VM I was having trouble.
>>
> That still suggests to me that something environmental is affecting
> that
> one particular PC's handling of floating-point math. Maybe something
> in
> your project is altering the RTL/CPU's floating-point settings at
> runtime.
> Or maybe the CPU is failing and needs to be replaced. Who knows.
>> data := EndOfTheDay(StrToDate('31/12/2014'));
>>
> Just an FYI, when you have a hard-coded date like that, you should use
> EncodeDate() instead of StrToDate() (and EncodeTime() for hard-coded
> times).
>
Eduardo wrote:
> I have created a small example to test this on another computer and
> for my surprise it worked inside the same VM I was having trouble.
That still suggests to me that something environmental is affecting that
one particular PC's handling of floating-point math. Maybe something in
your project is altering the RTL/CPU's floating-point settings at runtime.
Or maybe the CPU is failing and needs to be replaced. Who knows.
> data := EndOfTheDay(StrToDate('31/12/2014'));
Just an FYI, when you have a hard-coded date like that, you should use EncodeDate()
instead of StrToDate() (and EncodeTime() for hard-coded times).
--
Remy Lebeau (TeamB)
Eduardo wrote:
> I have created a small example to test this on another computer and
> for my surprise it worked inside the same VM I was having trouble.
That still suggests to me that something environmental is affecting that
one particular PC's handling of floating-point math. Maybe something in
your project is altering the RTL/CPU's floating-point settings at runtime.
Or maybe the CPU is failing and needs to be replaced. Who knows.
> data := EndOfTheDay(StrToDate('31/12/2014'));
Just an FYI, when you have a hard-coded date like that, you should use EncodeDate()
instead of StrToDate() (and EncodeTime() for hard-coded times).
--
Remy Lebeau (TeamB)
I have created a small example to test this on another computer and for my
surprise it worked inside the same VM I was having trouble.
As you can see there is nothing special, just what should be. The value comes
out as 31/12/2014 23:59:59.
Now my question, how can it turn differently in my other project? It is a
big project, hundreds of units.
The results of floating points are overall suffering of rounding problems.
With this test means that my compiler is generating correct code, even in
FMX platform (same as my other project).
However my current project is taken from the Dev VM computer and run somewhere
else it works correcly.
So there is some correlation between PC-Project
Any ideas?
Eduardo
{code}
unit Unit3;
interface
uses
System.DateUtils,
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.Edit;
type
TForm3 = class(TForm)
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
{$R *.fmx}
procedure TForm3.FormCreate(Sender: TObject);
var
data: TDateTime;
begin
data := EndOfTheDay(StrToDate('31/12/2014'));
Edit1.Text := DateToStr(Data);
end;
end.
{code}
> Eduardo wrote:
>
>> Both results are returning correctly the value for date = 31/12/2014
>> and for time = 30/12/1899 23:59:59
>>
>> Then at this line
>>
>> AValue := AValue + LTime
>>
>> it is going to 01/01/2015.
>>
> Remember that a TDateTime is implemented as a floating-point Double,
> where the integral portion is the date and the decimal portion is the
> time. What you describe implies that the addition of the two
> floating-point values is rounding up the result to the next whole
> integer. That is likely related to the other floating-point issue you
> reported earlier this morning. Maybe there is a bug in the latest
> compiler update, but it is more likely to be a bug in how your CPU
> handles floating-point math, or even in your VM system (did you try
> the same test without using a VM?).
>
> --
> Remy Lebeau (TeamB)
Eduardo wrote:
> Both results are returning correctly the value for date = 31/12/2014
> and for time = 30/12/1899 23:59:59
>
> Then at this line
>
> AValue := AValue + LTime
>
> it is going to 01/01/2015.
Remember that a TDateTime is implemented as a floating-point Double, where
the integral portion is the date and the decimal portion is the time. What
you describe implies that the addition of the two floating-point values is
rounding up the result to the next whole integer. That is likely related
to the other floating-point issue you reported earlier this morning. Maybe
there is a bug in the latest compiler update, but it is more likely to be
a bug in how your CPU handles floating-point math, or even in your VM system
(did you try the same test without using a VM?).
--
Remy Lebeau (TeamB)