Float, Real8, or Decimal?

Public support forum for peer to peer support with related to the Visual Objects and Vulcan.NET products
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Float, Real8, or Decimal?

Post by wriedmann »

Hi Arne,

I'm waiting for the moment when I can replace all floats in amounts with decimals - I'm very tired about all the issues with floats.

For other things like seconds() or others I a float is enough.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4907
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Float, Real8, or Decimal?

Post by Chris »

Hi Arne,

Indeed Seconds() returns a REAL8, that's because it is defined in XSharp.Core, which does not know about FLOATs, but can be easily moved to the other dlls and return a FLOAT instead. But it should not be really important, REAL8 and FLOAT are basically the same thing, FLOAT just has extra information about how to print the value (so about conversion to string), but that has nothing to do with calculations.

Val() returns a USUAL and USUALs can only hold INTs or FLOATs (And System.Decimal in X#), so it never returns a REAL8. But as I said this still should be no problem to use Val() together with either FLOATs or REAL8s.

Can you please post a sample code of something not behaving well? I suspect it is just a "showing on screen" issue, one of the REAL8/FLOAT/USUAL -> STRING functions not converting numbers to strings with the intended accuracy, or something along those lines.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
lumberjack
Posts: 727
Joined: Fri Sep 25, 2015 3:11 pm
Location: South Africa

Float, Real8, or Decimal?

Post by lumberjack »

Hi Arne,
ArneOrtlinghaus wrote: Stay with floats or convert to another type, that's the question...
I think sometimes we need to also ask, is floating points still necessary, or can we rather convert to integer types?
I had now an issue using the function Seconds() together with float variables in x#.
DOTNET allows us to completely move away from floating points in this scenario:

Code: Select all

local fsecstart := Seconds() as float
local fdiff as float
... do something
fdiff := Seconds()-fsecstart
// in the following condition the difference of the new seconds() 
// minus the previous seconds() call converted to float was unexpectedly  smaller than 0
// The reason seem to be the mixing of float and real8
// In the VO-program this was treated correctly, but also in the X#-Program converting everything to real8
if fdiff < 0   
  fdiff += 86400  // for midnight change
endif
This can easily be converted and obsoleting midnight rollover

Code: Select all

var dstart := DateTime.Now
... do something
var diff := DateTime.Now:Ticks - dstart:Ticks // No worry about midnight
Regards,
______________________
Johan Nel
Boshof, South Africa
User avatar
ArneOrtlinghaus
Posts: 412
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Float, Real8, or Decimal?

Post by ArneOrtlinghaus »

Hi Chris,

it took a while to make a sample program that shows the behavior. Now I have succeeded. It shows it only sometimes. So there is a loop of 100000 to have some occurrences. When changing the variables to real8, the behavior did not occur until now.
I have attached the project. It is the function testseconds.

Arne
Attachments
ConsoleApplication1.zip
(622.81 KiB) Downloaded 59 times
ConsoleApplication1.zip
(622.81 KiB) Downloaded 53 times
User avatar
ArneOrtlinghaus
Posts: 412
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Float, Real8, or Decimal?

Post by ArneOrtlinghaus »

Hi Johann,

interesting, that your example should work. I can't believe:-) How could they have implemented it, that it works?

var dstart := DateTime.Now
... do something
var diff := DateTime.Now:Ticks - dstart:Ticks // No worry about midnight
User avatar
lumberjack
Posts: 727
Joined: Fri Sep 25, 2015 3:11 pm
Location: South Africa

Float, Real8, or Decimal?

Post by lumberjack »

Hi Arne,
ArneOrtlinghaus wrote: interesting, that your example should work. I can't believe:-) How could they have implemented it, that it works?

Code: Select all

var dstart := DateTime.Now
... do something
var diff := DateTime.Now:Ticks - dstart:Ticks // No worry about midnight
Well I have not tested it, but... MinValue is in DOTNET terms the "Beginning of Time" (BoT), 10000 Ticks make 0.001 seconds. MaxValue is "End of Time" (EoT), which implies we need to finish our software before that Dooms/rollover tick.. :evil:

I had in Vulcan days actually published on the GrafX NG a DateClass where I played and encapsulated most of the Clipper Date functions using the DateTime class, DoW, MoY, etc. Also added some additional ones, B/EoQ(uarter), B/EoT(erm), B/EoS(emester) and a "Financial" class where the methods/properties adhere to a Financial year start (the first month of the FY) property. Might need to dig it up and ask Robert to publish it in the downloads/contrib area.

But in essence, it provides us with an alternative Seconds() function that will only not work at the EoT, instead of End of Day. We hopefully created a bug that will only be discovered "After our Time"... :)
______________________
Johan Nel
Boshof, South Africa
NickFriend
Posts: 248
Joined: Fri Oct 14, 2016 7:09 am

Float, Real8, or Decimal?

Post by NickFriend »

I may be wrong but I think you don't need to reference the ticks anyway.... Just DateTime.Now-dstart is sufficient and will return a TimeSpan.

Nick
User avatar
lumberjack
Posts: 727
Joined: Fri Sep 25, 2015 3:11 pm
Location: South Africa

Float, Real8, or Decimal?

Post by lumberjack »

Hi Nick,
NickFriend wrote:I may be wrong but I think you don't need to reference the ticks anyway.... Just DateTime.Now-dstart is sufficient and will return a TimeSpan.
Yes you are correct, I just used Ticks for explanatory purposes since Ticks provide a "unique" representation of a DateTime object.
Regards,
______________________
Johan Nel
Boshof, South Africa
User avatar
Chris
Posts: 4907
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Float, Real8, or Decimal?

Post by Chris »

Hi Arne,

Thanks, I see the problem and I found what's causing it, it's a bug in the "<" operator code for FLOATs, it does not treat the SetFloatDelta() correctly (if you set SetFloatDelta(0) then your code works fine). Will send you a fix for that.

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
ArneOrtlinghaus
Posts: 412
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Float, Real8, or Decimal?

Post by ArneOrtlinghaus »

Hi Chris,
thank you for verifying and resolving this. I didn't even know that there is this setfloatdelta after 20 years of VO programming....

Looking into ILSpy for me the influencing code seems to be in the class sharp.__Float in the xsharp.rt and there in the operator method
public static Logicoperator <(lhs as __Float , rhs as __Float )
where the floatdelta may influence the comparison result.
Similarly there are many other operators overwritten, that may influence behavior of float compared to real8.

The usual type seems to be the __Usual in the Xsharp.RT.
There is a similar operator
public static Logicoperator <(lhs as __Usual , rhs as __Usual )
When looking there what is inserted there it seems that always two real8 variables are compared.

I find this ok, because it seems that the usual type is performance optimized as much as possible, with the effect that it uses more real8 behavior than VO that seems to use the float variable behavior in usuals.

My conclusion is again for moving code from VO to X#:
Try to convert every float to real8, also if you use many usuals.
- The advantage is having always a clear floating behavior similar to other languages
- The performance and memory behavior is better.
- Compared to Float in VO there may be about two decimals less of accuracy, but the accuracy in X# should be equal for float and real8, because float is based on real8 (double).
- Limiting everything to exactly one floating type avoids strange behaviors difficult to understand.
- Comparison of equal between two floating numbers should work only if the numbers are really 0, same as for most other computer languages, otherwise always the absolute difference must be lower a certain limit.
- The biggest differences may appear using the function Str without specifying the number of decimals and the NTrim function. Obviously when using real8 there will be more decimals displayed. A possibility to use a substitution similar to the attached function NTrimSafe, that automatically removes 0 decimals. At least when assigning integer values to real8 this should display data without shocking users. Better is to use str always with a correct specification of the decimals.

Arne
Attachments
ntrimremovedecimals.txt
(3.03 KiB) Downloaded 65 times
Post Reply