Skip to content

Commit b9dd389

Browse files
authored
Fix float TryParse (#172)
***NO_CI***
1 parent a22fc17 commit b9dd389

File tree

2 files changed

+178
-22
lines changed

2 files changed

+178
-22
lines changed

Tests/NFUnitTestSystemLib/UnitTestParseTests.cs

Lines changed: 177 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ namespace NFUnitTestSystemLib
1313
[TestClass]
1414
class UnitTestParseTests
1515
{
16-
private static int[] _intArr = new int[0];
17-
16+
private static int[] _intArr = new int[0];
17+
1818
public static string[] GetRandomStringArray(int max, bool signed)
1919
{
2020
Random random = new Random();
2121

22-
string[] arr1 = new string[] {
22+
string[] arr1 = new string[] {
2323
"0",
2424
"-0",
2525
"+0",
@@ -129,8 +129,8 @@ public void ParseByte_Test_2()
129129
OutputHelper.WriteLine("Byte MaxValue = " + byte.MaxValue.ToString());
130130

131131
string[] strArr = GetRandomStringArray(byte.MaxValue, false);
132-
byte[] _byte = new byte[_intArr.Length];
133-
132+
byte[] _byte = new byte[_intArr.Length];
133+
134134
for (int i = 0; i < _byte.Length; i++)
135135
{
136136
_byte[i] = (byte)_intArr[i];
@@ -482,23 +482,17 @@ public void ParseDouble_Test_Valid_Values()
482482

483483
t = "1.7976931348623157E+308";
484484
Assert.Equal(double.MaxValue, double.Parse(t), "Testing double max value parse");
485-
486-
t = "-3.40282347E+38";
487-
Assert.Equal(float.MinValue, (float)double.Parse(t), "Testing float min value parse");
488-
489-
t = "3.40282347E+38";
490-
Assert.Equal(float.MaxValue, (float)double.Parse(t), "Testing float max value parse");
491485
}
492486

493487
[TestMethod]
494488
public void ParseDouble_Test_Invalid_Values()
495489
{
496490
string[] strArr = new string[] {
497-
"",
491+
"",
498492
" ",
499493
" ",
500494
"-0e-a",
501-
"+123a4",
495+
"+123a4",
502496
" +123f.1",
503497
"123ea2",
504498
"1.111.1",
@@ -537,13 +531,175 @@ public void ParseDouble_OverflowTests()
537531

538532
t = "1.7976931348623180E+308";
539533
Assert.Equal(double.PositiveInfinity, double.Parse(t), "High positive values should return double.PositiveInfinity value when parsed");
534+
}
535+
536+
[TestMethod]
537+
public void ParseFloat_Test_Valid_Values()
538+
{
539+
string[] strArr = new string[] {
540+
"0",
541+
"-0",
542+
"+0",
543+
"00000 ",
544+
" -00000",
545+
" +00000 ",
546+
" 0 ",
547+
" -00000 ",
548+
"+123",
549+
" +123 ",
550+
" +123",
551+
"+123 ",
552+
"567.89",
553+
"-567.89",
554+
"1E23",
555+
"9007199254740997.0",
556+
"9007199254740997.00000000000000000000000000000000000000000000000000000",
557+
"5.005",
558+
"5.050",
559+
"50050.0",
560+
"0.005",
561+
"6250000000000000000000000000000000e-12",
562+
"6250000e0",
563+
"6250100e-5",
564+
"625010.00e-4",
565+
"62500e-4",
566+
"62500",
567+
"10e-3"
568+
};
569+
570+
float[] _float = new float[] {
571+
0,
572+
0,
573+
0,
574+
0,
575+
0,
576+
0,
577+
0,
578+
0,
579+
123,
580+
123,
581+
123,
582+
123,
583+
567.89f,
584+
-567.89f,
585+
1E23f,
586+
9007199254740997.0f,
587+
9007199254740996.0f,
588+
5.005f,
589+
5.050f,
590+
50050.0f,
591+
0.005f,
592+
6250000000000000000000000000000000e-12f,
593+
6.25e6f,
594+
62.501f,
595+
62.501f,
596+
6.25f,
597+
62500,
598+
0.01f
599+
};
540600

541-
t = "-3.40282380E+38";
601+
float result;
602+
for (int i = 0; i < strArr.Length; i++)
603+
{
604+
OutputHelper.WriteLine($"Parsing {strArr[i]} expecting: {_float[i]}");
605+
606+
Assert.Equal(float.Parse(strArr[i]), _float[i], $"Failed while parsing string: {strArr[i]} expecting: {_float[i]}");
607+
608+
Assert.True(float.TryParse(strArr[i], out result), $"TryParse failed for {strArr[i]} expecting: {_float[i]}");
609+
Assert.Equal(_float[i], result);
610+
}
611+
612+
float f = float.Parse("-0.1");
613+
Assert.Equal(f, -0.1f);
614+
615+
Assert.True(float.TryParse("-0.1", out result), $"TryParse failed for -0.1 expecting: {f}");
616+
Assert.Equal(-0.1f, result);
617+
618+
f = float.Parse("0.1");
619+
Assert.Equal(f, 0.1f);
620+
621+
Assert.True(float.TryParse("0.1", out result), $"TryParse failed for 0.1 expecting: {f}");
622+
Assert.Equal(0.1f, result);
623+
624+
f = float.Parse(" -1.1");
625+
Assert.Equal(f, -1.1f);
626+
627+
Assert.True(float.TryParse(" -1.1", out result), $"TryParse failed for -1.1 expecting: {f}");
628+
Assert.Equal(-1.1f, result);
629+
630+
f = float.Parse(" -0.0001");
631+
Assert.Equal(f, -0.0001f);
632+
633+
Assert.True(float.TryParse(" -0.0001", out result), $"TryParse failed for -0.0001 expecting: {f}");
634+
Assert.Equal(-0.0001f, result);
635+
636+
f = float.Parse(" -10.0001");
637+
Assert.Equal(f, -10.0001f);
638+
639+
Assert.True(float.TryParse(" -10.0001", out result), $"TryParse failed for -10.0001 expecting: {f}");
640+
Assert.Equal(-10.0001f, result);
641+
642+
f = float.Parse("-0.01e-10");
643+
Assert.Equal(f, -0.01e-10f);
644+
645+
Assert.True(float.TryParse("-0.01e-10", out result), $"TryParse failed for -0.01e-10 expecting: {f}");
646+
Assert.Equal(-0.01e-10f, result);
647+
648+
// can't use Min/MaxValue.ToString() because the fast float-to-string routine only works in the range 2^64 to 2^-64 (there-about).
649+
string t = "-3.40282347E+38"; // float.MinValue
650+
Assert.Equal(float.MinValue, float.Parse(t), "Testing float min value parse");
651+
652+
t = "3.40282347E+38"; // float.MaxValue
653+
Assert.Equal(float.MaxValue, float.Parse(t), "Testing float max value parse");
654+
}
655+
656+
[TestMethod]
657+
public void ParseFloat_Test_Invalid_Values()
658+
{
659+
string[] strArr = new string[] {
660+
"",
661+
" ",
662+
" ",
663+
"-0e-a",
664+
"+123a4",
665+
" +123f.1",
666+
"123ea2",
667+
"1.111.1",
668+
" -123-e3",
669+
" 123.456 777",
670+
"1234567ee73",
671+
" +1234e-77+",
672+
"++1",
673+
"--1",
674+
"+1+",
675+
" .1123abc",
676+
" .123+456",
677+
"+123e++10",
678+
"+123e--10",
679+
"-123e++10"
680+
};
681+
682+
for (int i = 0; i < strArr.Length; i++)
683+
{
684+
OutputHelper.WriteLine($"parse {strArr[i]}");
685+
686+
Assert.Throws(typeof(FormatException),
687+
() => { float.Parse(strArr[i]); },
688+
$"Should throw exception of type FormatExeception while parsing string: '{strArr[i]}'");
689+
690+
Assert.False(float.TryParse(strArr[i], out float _), $"TryParse should return false while parsing string: '{strArr[i]}'");
691+
}
692+
}
693+
694+
[TestMethod]
695+
public void ParseFloat_OverflowTests()
696+
{
697+
// Note we have to check hex values - again, the ToString() works over a subset of the range for double/float, and returns 'oor' or '-oor' for anything outside that range
698+
string t = "-3.40282380E+38";
542699
Assert.Equal(float.NegativeInfinity, float.Parse(t), "High negative values should return float.NegativeInfinity value when parsed");
543700

544701
t = "3.40282380E+38";
545702
Assert.Equal(float.PositiveInfinity, float.Parse(t), "High positive values should return float.PositiveInfinity value when parsed");
546-
547703
}
548704

549705
private void CheckUValues(ulong start)
@@ -849,8 +1005,8 @@ public void ParseByte_FormatException_Test_26()
8491005

8501006
for (int i = 0; i < 5; i++)
8511007
{
852-
string rdmString = GetRandomString();
853-
1008+
string rdmString = GetRandomString();
1009+
8541010
Assert.Throws(typeof(FormatException), () => { _ = byte.Parse(rdmString); }, $"Random string '{rdmString}' did not throw exception of FormatException");
8551011

8561012
Assert.False(byte.TryParse(rdmString, out _));
@@ -863,8 +1019,8 @@ public void ParseInt16_FormatException_Test_27()
8631019
string[] strArr = new string[] { "", "1,234", "123e5", "a", "3.14159265358979" };
8641020
for (int i = 0; i < strArr.Length; i++)
8651021
{
866-
Assert.Throws(typeof(FormatException), () => { _ = short.Parse(strArr[i]); });
867-
1022+
Assert.Throws(typeof(FormatException), () => { _ = short.Parse(strArr[i]); });
1023+
8681024
Assert.False(short.TryParse(strArr[i], out _));
8691025
}
8701026
for (int i = 0; i < 5; i++)
@@ -1133,8 +1289,8 @@ public void box_unbox_Test_1()
11331289
// Try casts that shoud succeed. Any exception here means failure.
11341290
// First we try casts that should succeed.
11351291
// Casts between enums with the same basic type
1136-
MyEnum2 e2 = (MyEnum2)o_enum; // line 2
1137-
// Cast from enum to primitive type that enum is based on
1292+
MyEnum2 e2 = (MyEnum2)o_enum; // line 2
1293+
// Cast from enum to primitive type that enum is based on
11381294
short sv = (short)o_enum;
11391295
Assert.Equal(sv, (short)MyEnum.Value);
11401296

nanoFramework.CoreLibrary/System/Single.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public static bool TryParse(
183183
{
184184
result = (float)Convert.NativeToDouble(
185185
s,
186-
true,
186+
false,
187187
out bool success);
188188

189189
return success;

0 commit comments

Comments
 (0)