-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
Switch expression in C# 8 behaves differently on x86 vs x64 Android. After third call it behaves differently for float type.
Reproduction Steps
Copy paste the below code in mono/samples/Android and try to run on x86 android emulator.
GetNumberAsString after third call starts returning NAN, even if it is called for the same value (float.MaxValue).
public static int Main(string[] args)
{
var random = new Random(42);
List<float> Floats = new List<float>
{
// 0.000f,
//1.1234e1f,
//-1.1234e1f,
float.MaxValue,
float.MinValue
};
for (int i = 0; i < 10; i++)
{
float value = NextFloat(random);
Floats.Add(value);
}
Console.WriteLine ("GetNumberAsString conversion is {0}", GetNumberAsString(float.MaxValue));
Console.WriteLine ("GetNumberAsString conversion is {0}", GetNumberAsString(Floats[3]));
Console.WriteLine ("GetNumberAsString conversion is {0}", GetNumberAsString(Floats[4]));
Console.WriteLine ("GetNumberAsString conversion is {0}", GetNumberAsString(Floats[5]));
Console.WriteLine ("GetNumberAsString conversion is {0}", GetNumberAsString(float.MaxValue));
//RunAsRootTypeTest(Floats);
return 42;
}
public static float NextFloat(Random random)
{
double mantissa = (random.NextDouble() * 2.0) - 1.0;
double exponent = Math.Pow(2.0, random.Next(-126, 128));
float value = (float)(mantissa * exponent);
return value;
}
private static void RunAsRootTypeTest<T>(List<T> Floats)
{
foreach(T f in Floats)
{
Console.WriteLine ("GetNumberAsString from foreach conversion is {0}", GetNumberAsString(f));
}
}
private static string GetNumberAsString<T>(T number)
{
/*switch (Type.GetTypeCode(typeof(T)))
{
case TypeCode.Double:
return Convert.ToDouble(number).ToString("G9", System.Globalization.CultureInfo.InvariantCulture);
case TypeCode.Single:
return Convert.ToSingle(number).ToString("G9", System.Globalization.CultureInfo.InvariantCulture);
case TypeCode.Decimal:
return Convert.ToDecimal(number).ToString(System.Globalization.CultureInfo.InvariantCulture);
default:
return number.ToString();
}*/
return number switch
{
double @double => @double.ToString("G9", System.Globalization.CultureInfo.InvariantCulture),
float @float => @float.ToString("G9", System.Globalization.CultureInfo.InvariantCulture),
decimal @decimal => @decimal.ToString(System.Globalization.CultureInfo.InvariantCulture),
_ => number.ToString()
};
}Expected behavior
GetNumberAsString should convert correctly after third call also.
To get expected behaviour please uncomment first switch in GetNumberAsString and comment last one.
TypeCode enum switch works correct on both x64 and x86, so my guess is switch expression in C# 8 behaves differently on x86 vs x64 Android.
Actual behavior
First 3 times GetNumberAsString returns correct value. After that it starts to return NAN.
Regression?
No response
Known Workarounds
Using TypeCode enum switch works fine on both x64 and x86.
Configuration
Try on Android x86.
Other information
return number switch
{
//double @double => @double.ToString("G9", System.Globalization.CultureInfo.InvariantCulture),
float @float => @float.ToString("G9", System.Globalization.CultureInfo.InvariantCulture),
//decimal @decimal => @decimal.ToString(System.Globalization.CultureInfo.InvariantCulture),
_ => number.ToString()
};When I comment other cases in switch seems it works.