namespace ConsoleApplication15;
interface
uses
System.Linq;
type
Program = class
public
class method Main(args: array of String): Int32;
end;
implementation
class method Program.Main(args: array of String): Int32;
begin
var i : Integer := 230 ;
if i in [210..230] then
writeLn('OK')
else
writeLn('ERR');
end;
end.
The console app project works fine (OK result) in .NET, .NET core 2.2.x, but not in .NET core 3.x. (ERR result). Why? Is this a platform problem (I also noticed different test results after changing 2.2.x to 3.1 in real projects) or Elements compiler change (we updated to build .2505)?
I also noticed a double-precision change between core 2.2 and 3 when using Convert.ToString(double), e.g. 100.1 sometimes returns 100.100000000001 but it’s a different issue.
Well, does the rust change between .NET and .NET Core 3, when both versions are built with 2505?
But FWIW I can reproduce this. your code gives ok OK when I run on Mono, and ERR when I run on .NET Core 2.2, and ERR on .NET Core 3 and 5.
Since we don’t do anything differently compiler side between .NET Core versions (or, really, between Core and regular), I’m sure thins something that changed/broke in the runtime; but of course it’s our problem to compensates for that, so this is a compiler bug.
The error only seems to hit at the very end of the ranger eg:
class method Program.Main(args: array of String): Int32;
begin
var i : Integer := 230 ;
writeLn($'i {i}'); // 230
writeLn($'i >= 210 {i >= 210}'); // True
writeLn($'i ≤ 230 {i ≤ 230}'); // True
if i in [210..230] then
writeLn('OK')
else
writeLn('ERR'); // ERR
if i in [210..231] then
writeLn('OK2') // OK2
else
writeLn('ERR2');
end;
That very likely sounds like a runtime thing too; we don’t calculate that stuff ourselves, we just use the platform APIs. In particular, Elements RTL’s Convert.ToDouble uses this code — do you see the same difference if you use Double.TryParse( yourself directly?
var lResult: Double;
if Double.TryParse(aValue, System.Globalization.NumberStyles.Any, aLocale, out lResult) then
exit valueOrDefault(lResult);