[Mono-list] More .NET and mono floating point inconsistencies

ddambro ddambro at gmail.com
Sat Feb 21 21:06:11 EST 2009


Kornél,

Thank you for looking into this issue for me.  After adding a few more
explicit float conversions and removing some temporary variables, I was able
to create a version of my program that runs the same on both mono
(svn127604) and .NET.  However, I am interested in what you said about
doubles.  If I'm understanding correctly, if I use doubles instead of floats
I shouldn't have to worry about these rounding inconsistencies?  I think we
started with doubles, but moved to floats because they were supposedly
faster, but if what you say is true, I might try and change everything over
when I have time.  Checking Google only reveals that there is some conflict
as to if floats are faster than doubles in C#.  Plus if I ever decide to use
the SIMD instructions, I can only do half as much work at a time.  But even
if there is a performance loss it might be worth it to avoid constantly
having to test new versions for .NET/mono compatibility.

David


Kornél Pál wrote:
> 
> David,
> 
> I've evaluated your test cases and found that the behavior exposed by 
> your tests cases is not a bug.
> 
> For the first sight this seems to be a bug is MS.NET, but it isn't a bug 
> of MS.NET either.
> 
> ECMA specs (part3, 1.1.1 Numeric data types) explicitly state the
> following:
> 
> When a floating-point value ... is put in a storage location, it is 
> automatically coerced to the type of the storage location. ... However,
> the value might be retained in the internal representation for future 
> use, if it is reloaded from the storage location without having been 
> modified. ... This freedom to carry extra precision is not permitted,
> however, following the execution of an explicit conversion (conv.r4 or 
> conv.r8) ...
> 
> This means that unlike integer variables, floating point store/load 
> pairs are not (necessarily) cause conversion.
> 
> On the other hand if you need deterministic behavior, you should issue 
> an explicit conv.r4 (x = (float)y; in C#) because this is an 
> implementation detail of the current MS JIT compiler that may change in 
> the future even in that compiler.
> 
> Although ECMA specs permit the native float type to have additional 
> precision, you will most likely never notice the same behavior with 
> double (float64), because both Mono and MS.NET configure the FPU to 
> round each arithmetic operations to 64-bits.
> 
> Also note that there is no performance gain from using float (float32), 
> because the FPU still operates in 64-bit mode that has to be converted 
> to 32-bits. As a result if you want performance you shouldn't use 
> float32 at all.
> 
> A simplified test case:
> float f1=200;
> float f2=162.980057f;
> float f3 = (1 - (f2 / f1));
> float f4 = f3*f3;
> Console.WriteLine(f4.ToString("R", CultureInfo.InvariantCulture));
> 
> Adding an extra conversion you will get the behavior of Mono on MS.NET 
> as well:
> float f1=200;
> float f2=162.980057f;
> float f3 = (float)(1 - (f2 / f1));
> float f4 = f3*f3;
> Console.WriteLine(f4.ToString("R", CultureInfo.InvariantCulture));
> 
> Kornél
> 
> Rodrigo Kumpera wrote:
>> I have commited the fixed from Kornél for all bugs that have tests.
>> 
>> On Fri, Feb 20, 2009 at 12:14 AM, ddambro <ddambro at gmail.com 
>> <mailto:ddambro at gmail.com>> wrote:
>> 
>> 
>>     Hi,
>> 
>>     Thanks for looking into my issues.  I hope my post didn't come across
>> as
>>     rude or anything, I was really just looking to ask if it was better
>>     to post
>>     issues here or directly to Bugzilla.  I'm sure there are far more
>>     important
>>     issues than my weird floating point inconsistencies.
>> 
>>     For the curious, I am an AI researcher working on Evolutionary
>>     Computation.
>>     I tend to use Windows and .NET to run my code, but my research group
>> has
>>     several large computing clusters that could massively speed up my
>>     experiments, but they only run Linux. Also academia tends to shy
>>     away from
>>     "Windows Only" software, so if I can say "Runs in Linux" when I
>>     release my
>>     code to the public, it's a pretty big boon for me as well as the
>>     people who
>>     want to run it.  However, because of the floating point issues
>>     described,
>>     experiments run on mono are not compatible with experiments run on
>>     .NET, as
>>     over the course of a simulation, the small errors propagate over
>>     thousands
>>     of time steps into large differences in the final AI behavior.
>>      Thus, if I
>>     used both mono and .NET, not only would I have to be mindful of which
>>     experiment was run on which platform when I do analysis and
>>     demonstrations,
>>     but when I release my results to the public I would also have to mark
>>     arbitrary sets of experiments as "mono only" or ".NET only."
>> 
>> 
>>     Kornél Pál wrote:
>>      >
>>      > Hi,
>>      >
>>      > Thanks for the test cases, I'll invetigate these as well and try
>>     to fix
>>      > them.
>>      >
>>      > The best way to get bugs fixed is to produce test cases and
>>     report them
>>      > in buzilla.
>>      >
>>      > You can help more if you are able to provide a patch to fix the
>> bugs.
>>      >
>>      > Note that for some reasons Novell guys seem to ignore this bug
>> mostly
>>      > because they have other things to do and their approval is
>>     required for
>>      > these changes.
>>      >
>>      > Could you please describe your scenario (application name,
>>     purpose, etc.
>>      > if they are public) where you need these floating point roundings
>> and
>>      > describe why these bugs are critical for you.
>>      >
>>      > Providing some description may raise component owners' attention.
>>      >
>>      > Kornél
>>      >
>>      > ddambro wrote:
>>      >> I previously posted about some differences I noticed between the
>>     floating
>>      >> point math in .NET and mono
>>      >>
>>    
>> http://www.nabble.com/Mono-and-.Net-Floating-Point-Inconsistencies-to21428695ef1367.html
>>      >> here .  The bug report can be found
>>      >> https://bugzilla.novell.com/show_bug.cgi?id=467201 here .  The
>> patch
>>      >> provided (Thank you!) fixes several issues I was encountering,
>> but
>>      >> unfortunately it led me to discover a couple more.  The
>>     following two
>>      >> code
>>      >> samples were tested x86 machines using Linux mono 2.2 with the
>> patch
>>      >> found
>>      >> in the bug report, a clean Windows mono 2.0.1, and the latest
>>     version of
>>      >> .NET targeting 3.0 framework and x86.
>>      >>
>>      >> ---
>>      >> 1.
>>      >>
>>      >> using System;
>>      >> using System.Runtime.CompilerServices;
>>      >>
>>      >> class Testing
>>      >> {
>>      >>     [MethodImpl(MethodImplOptions.NoInlining)]
>>      >>     public static void Main()
>>      >>     {
>>      >>         float f1=200;
>>      >>
>>      >>         float distance=Distance(300, 500, 387.5f, 362.5f);
>>      >>
>>      >>         float dist = 1 - (distance / f1);
>>      >>
>>      >>         float distSqud = dist * dist;
>>      >>
>>      >>         Console.WriteLine(distSqud.ToString("R"));
>>      >>
>>      >>         foreach (byte b in BitConverter.GetBytes(distSqud))
>>      >>             Console.WriteLine(b);
>>      >>
>>      >>     }
>>      >>
>>      >>     public static float Distance(float x1, float y1, float x2,
>>     float y2)
>>      >>     {
>>      >>         float xDist = x1 - x2;
>>      >>         float yDist = y1 - y2;
>>      >>         float dist = (float)Math.Sqrt(xDist * xDist + yDist *
>>     yDist);
>>      >>         return dist;
>>      >>     }
>>      >>
>>      >> On .NET this code produces:
>>      >> 0.0342619047
>>      >> 54
>>      >> 86
>>      >> 12
>>      >> 61
>>      >>
>>      >> and on mono it produces:
>>      >> 0.03426191
>>      >> 55
>>      >> 86
>>      >> 12
>>      >> 61
>>      >>
>>      >> ---
>>      >> 2.
>>      >>
>>      >> using System;
>>      >> using System.Runtime.CompilerServices;
>>      >>
>>      >> class Testing
>>      >> {
>>      >>     [MethodImpl(MethodImplOptions.NoInlining)]
>>      >>     public static void Main()
>>      >>     {
>>      >>         float distance = Distance(616.161255f, 391.2928f,
>> 550.8382f,
>>      >> 131.006973f);
>>      >>         Console.WriteLine(distance.ToString("R"));
>>      >>
>>      >>         foreach (byte b in BitConverter.GetBytes(distance))
>>      >>             Console.WriteLine(b);
>>      >>     }
>>      >>
>>      >>     public static float Distance(float x1, float y1, float x2,
>>     float y2)
>>      >>     {
>>      >>         float xDist = x1 - x2;
>>      >>         float yDist = y1 - y2;
>>      >>         float dist = (float)Math.Sqrt(xDist * xDist + yDist *
>>     yDist);
>>      >>
>>      >>         Console.WriteLine(dist.ToString("R"));
>>      >>
>>      >>         foreach (byte b in BitConverter.GetBytes(dist))
>>      >>             Console.WriteLine(b);
>>      >>
>>      >>         return dist;
>>      >>     }
>>      >> }
>>      >>
>>      >> On .NET this code produces:
>>      >> 268.3576
>>      >> 198
>>      >> 45
>>      >> 134
>>      >> 67
>>      >> 268.3576
>>      >> 198
>>      >> 45
>>      >> 134
>>      >> 67
>>      >>
>>      >> and on mono it produces:
>>      >> 268.357635
>>      >> 199
>>      >> 45
>>      >> 134
>>      >> 67
>>      >> 268.357635
>>      >> 199
>>      >> 45
>>      >> 134
>>      >> 67
>>      >>
>>      >> ---
>>      >> These seem to be very similar to the issues I was encountering
>>     before,
>>      >> but
>>      >> they are not fixed by the patch.  What is the best way to
>>     resolve these
>>      >> inconsistencies?
>>      >>
>>      >> Thanks,
>>      >> David
>>      > _______________________________________________
>>      > Mono-list maillist  -  Mono-list at lists.ximian.com
>>     <mailto:Mono-list at lists.ximian.com>
>>      > http://lists.ximian.com/mailman/listinfo/mono-list
>>      >
>>      >
>> 
>>     --
>>     View this message in context:
>>    
>> http://www.nabble.com/More-.NET-and-mono-floating-point-inconsistencies-tp22018718p22114104.html
>>     Sent from the Mono - General mailing list archive at Nabble.com.
>> 
>>     _______________________________________________
>>     Mono-list maillist  -  Mono-list at lists.ximian.com
>>     <mailto:Mono-list at lists.ximian.com>
>>     http://lists.ximian.com/mailman/listinfo/mono-list
>> 
>> 
>> 
>> ------------------------------------------------------------------------
>> 
>> _______________________________________________
>> Mono-list maillist  -  Mono-list at lists.ximian.com
>> http://lists.ximian.com/mailman/listinfo/mono-list
> _______________________________________________
> Mono-list maillist  -  Mono-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list
> 
> 

-- 
View this message in context: http://www.nabble.com/More-.NET-and-mono-floating-point-inconsistencies-tp22018718p22142912.html
Sent from the Mono - General mailing list archive at Nabble.com.



More information about the Mono-list mailing list