CodeConverter
CodeConverter copied to clipboard
VB -> C#: Optimize Double(/Decimal)-to-Integer conversion
VB.Net input code
Imports System
Public Class A
Public Shared Sub Main()
Dim foo = 0.6
Dim bar = CInt(Math.Truncate(foo))
Dim baz = CInt(Math.Ceiling(foo))
Console.WriteLine(bar)
Console.WriteLine(baz)
End Sub
End Class
Erroneous output
using System;
public partial class A
{
public static void Main()
{
double foo = 0.6d;
int bar = (int)Math.Round(Math.Truncate(foo));
int baz = (int)Math.Round(Math.Ceiling(foo));
Console.WriteLine(bar);
Console.WriteLine(baz);
}
}
Extra verbose Math.Round
Expected output
using System;
public partial class A
{
public static void Main()
{
double foo = 0.6d;
int bar = (int)foo;
int baz = (int)Math.Ceiling(foo);
Console.WriteLine(bar);
Console.WriteLine(baz);
}
}
Decimal
is not optimized by the latest VB compiler but I think it can be.
CInt(Decimal)
→ System.Convert.ToInt32
(similar as (int)Math.Round
)
Details
- Product in use: online
- Version in use: e.g. 5.6.3 or a commit hash (if it's a 3rd party tool using this library, try one of the above)
- Did you see it working in a previous version, which? No
- Any other relevant information to the issue, or your interest in contributing a fix.
Just to make sure I understand, I assume you mean that methods already returning integers (floor, ceiling, truncate, round) don't need an additional round to be added?
Those methods return values whose types are same as input. VB does bankers' rounding but C# does truncation when converting floating points to integers.
https://sharplab.io/#v2:DYLgbgRgNAJiDUAfAkgWwA4HsBOAXAzgAQDKAnvrgKaoCwAUPQAoCuEwAlgMaEDCwAhviIBBeoXGEWbLiQAW/bJRglWhALL92AOwAUASjESjAEXapCAM0yZCAXkIAGAHQA2Q0fGnzEBXd7ItXB0NXFknABVsZi1OfiodK0w9AzoPCS9CHwAvPx4AoJCwnkp2Di0AcwTrZPcPHkwtfExgSicAdWx2KgAZbUodH2wUtPF6xubWjq7KXq1+7OGJAFEtZWJWehXlPkF8IA==
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue | DebuggableAttribute.DebuggingModes.DisableOptimizations)]
[assembly: AssemblyVersion("0.0.0.0")]
public class A
{
public static void Main()
{
double num = 0.6;
checked
{
int value = (int)num;
int value2 = (int)Math.Ceiling(num);
Console.WriteLine(value);
Console.WriteLine(value2);
}
}
}
https://learn.microsoft.com/en-us/dotnet/api/system.math.truncate?view=net-7.0
Starting with Visual Basic 15.8, the performance of Double-to-integer conversion is optimized if you pass the value returned by the Truncate method to the any of the integral conversion functions, or if the Double value returned by Truncate is automatically converted to an integer with Option Strict set to Off. This optimization allows code to run faster -- up to twice as fast for code that does a large number of conversions to integer types. The following example illustrates such an optimized conversion:
https://sharplab.io/#v2:DYLgbgRgPgkgtgBwPYCcAuBnABAZQJ4ZoCmcAsAFAUAKArhMAJYDGWAwsAIYbYCCFWArLXrNcACw4oiAE1x0sAWQ4MAdgAoAlP0E6AIgzhYAZkiRYAvFgAMAOgBs2nQP2GIki2xgq0apWjE2ACooNCpMHMRqJkgaWuROgi5YbgBeHqxePn4BrEQMjCoA5lGmsY5OrEgqGEjARDYA6igMxAAyqkRqbihxCQKV1bX1TS1E7Sqdqb2CAKIqsjh0FHOy7FwYQA==
VB compiler (LocalRewriter) in Roslyn has already done this optimization for Double
. However, it has no plan for Decimal
in the future.
https://sourceroslyn.io/#Microsoft.CodeAnalysis.VisualBasic/Lowering/LocalRewriter/LocalRewriter_Conversion.vb,921944f13b116c29,references