@@ -55,6 +55,10 @@ static float StrtofChar(const char* str, int exponent) {
5555 return Strtof (StringToVector (str), exponent);
5656}
5757
58+ static float StrtofTrimmedChar (const char * str, int exponent) {
59+ return StrtofTrimmed (StringToVector (str), exponent);
60+ }
61+
5862
5963TEST (Strtod) {
6064 Vector<const char > vector;
@@ -876,6 +880,194 @@ TEST(Strtof) {
876880
877881}
878882
883+ TEST (StrtofTrimmed) {
884+ Vector<const char > vector;
885+
886+ vector = StringToVector (" 1" );
887+ CHECK_EQ (1 .0f , StrtofTrimmed (vector, 0 ));
888+ CHECK_EQ (10 .0f , StrtofTrimmed (vector, 1 ));
889+ CHECK_EQ (100 .0f , StrtofTrimmed (vector, 2 ));
890+ CHECK_EQ (1e20f, StrtofTrimmed (vector, 20 ));
891+ CHECK_EQ (1e22f, StrtofTrimmed (vector, 22 ));
892+ CHECK_EQ (1e23f, StrtofTrimmed (vector, 23 ));
893+ CHECK_EQ (1e35f, StrtofTrimmed (vector, 35 ));
894+ CHECK_EQ (1e36f, StrtofTrimmed (vector, 36 ));
895+ CHECK_EQ (1e37f, StrtofTrimmed (vector, 37 ));
896+ CHECK_EQ (1e-1f , StrtofTrimmed (vector, -1 ));
897+ CHECK_EQ (1e-2f , StrtofTrimmed (vector, -2 ));
898+ CHECK_EQ (1e-5f , StrtofTrimmed (vector, -5 ));
899+ CHECK_EQ (1e-20f , StrtofTrimmed (vector, -20 ));
900+ CHECK_EQ (1e-22f , StrtofTrimmed (vector, -22 ));
901+ CHECK_EQ (1e-23f , StrtofTrimmed (vector, -23 ));
902+ CHECK_EQ (1e-25f , StrtofTrimmed (vector, -25 ));
903+ CHECK_EQ (1e-39f , StrtofTrimmed (vector, -39 ));
904+
905+ vector = StringToVector (" 2" );
906+ CHECK_EQ (2 .0f , StrtofTrimmed (vector, 0 ));
907+ CHECK_EQ (20 .0f , StrtofTrimmed (vector, 1 ));
908+ CHECK_EQ (200 .0f , StrtofTrimmed (vector, 2 ));
909+ CHECK_EQ (2e20f, StrtofTrimmed (vector, 20 ));
910+ CHECK_EQ (2e22f, StrtofTrimmed (vector, 22 ));
911+ CHECK_EQ (2e23f, StrtofTrimmed (vector, 23 ));
912+ CHECK_EQ (2e35f, StrtofTrimmed (vector, 35 ));
913+ CHECK_EQ (2e36f, StrtofTrimmed (vector, 36 ));
914+ CHECK_EQ (2e37f, StrtofTrimmed (vector, 37 ));
915+ CHECK_EQ (2e-1f , StrtofTrimmed (vector, -1 ));
916+ CHECK_EQ (2e-2f , StrtofTrimmed (vector, -2 ));
917+ CHECK_EQ (2e-5f , StrtofTrimmed (vector, -5 ));
918+ CHECK_EQ (2e-20f , StrtofTrimmed (vector, -20 ));
919+ CHECK_EQ (2e-22f , StrtofTrimmed (vector, -22 ));
920+ CHECK_EQ (2e-23f , StrtofTrimmed (vector, -23 ));
921+ CHECK_EQ (2e-25f , StrtofTrimmed (vector, -25 ));
922+ CHECK_EQ (2e-39f , StrtofTrimmed (vector, -39 ));
923+
924+ vector = StringToVector (" 9" );
925+ CHECK_EQ (9 .0f , StrtofTrimmed (vector, 0 ));
926+ CHECK_EQ (90 .0f , StrtofTrimmed (vector, 1 ));
927+ CHECK_EQ (900 .0f , StrtofTrimmed (vector, 2 ));
928+ CHECK_EQ (9e20f, StrtofTrimmed (vector, 20 ));
929+ CHECK_EQ (9e22f, StrtofTrimmed (vector, 22 ));
930+ CHECK_EQ (9e23f, StrtofTrimmed (vector, 23 ));
931+ CHECK_EQ (9e35f, StrtofTrimmed (vector, 35 ));
932+ CHECK_EQ (9e36f, StrtofTrimmed (vector, 36 ));
933+ CHECK_EQ (9e37f, StrtofTrimmed (vector, 37 ));
934+ CHECK_EQ (9e-1f , StrtofTrimmed (vector, -1 ));
935+ CHECK_EQ (9e-2f , StrtofTrimmed (vector, -2 ));
936+ CHECK_EQ (9e-5f , StrtofTrimmed (vector, -5 ));
937+ CHECK_EQ (9e-20f , StrtofTrimmed (vector, -20 ));
938+ CHECK_EQ (9e-22f , StrtofTrimmed (vector, -22 ));
939+ CHECK_EQ (9e-23f , StrtofTrimmed (vector, -23 ));
940+ CHECK_EQ (9e-25f , StrtofTrimmed (vector, -25 ));
941+ CHECK_EQ (9e-39f , StrtofTrimmed (vector, -39 ));
942+
943+ vector = StringToVector (" 12345" );
944+ CHECK_EQ (12345 .0f , StrtofTrimmed (vector, 0 ));
945+ CHECK_EQ (123450 .0f , StrtofTrimmed (vector, 1 ));
946+ CHECK_EQ (1234500 .0f , StrtofTrimmed (vector, 2 ));
947+ CHECK_EQ (12345e20f, StrtofTrimmed (vector, 20 ));
948+ CHECK_EQ (12345e22f, StrtofTrimmed (vector, 22 ));
949+ CHECK_EQ (12345e23f, StrtofTrimmed (vector, 23 ));
950+ CHECK_EQ (12345e30f, StrtofTrimmed (vector, 30 ));
951+ CHECK_EQ (12345e31f, StrtofTrimmed (vector, 31 ));
952+ CHECK_EQ (12345e32f, StrtofTrimmed (vector, 32 ));
953+ CHECK_EQ (12345e-1f , StrtofTrimmed (vector, -1 ));
954+ CHECK_EQ (12345e-2f , StrtofTrimmed (vector, -2 ));
955+ CHECK_EQ (12345e-5f , StrtofTrimmed (vector, -5 ));
956+ CHECK_EQ (12345e-20f , StrtofTrimmed (vector, -20 ));
957+ CHECK_EQ (12345e-22f , StrtofTrimmed (vector, -22 ));
958+ CHECK_EQ (12345e-23f , StrtofTrimmed (vector, -23 ));
959+ CHECK_EQ (12345e-25f , StrtofTrimmed (vector, -25 ));
960+ CHECK_EQ (12345e-39f , StrtofTrimmed (vector, -39 ));
961+
962+ vector = StringToVector (" 12345678901234" );
963+ CHECK_EQ (12345678901234 .0f , StrtofTrimmed (vector, 0 ));
964+ CHECK_EQ (123456789012340 .0f , StrtofTrimmed (vector, 1 ));
965+ CHECK_EQ (1234567890123400 .0f , StrtofTrimmed (vector, 2 ));
966+ CHECK_EQ (12345678901234e20f, StrtofTrimmed (vector, 20 ));
967+ CHECK_EQ (12345678901234e22f, StrtofTrimmed (vector, 22 ));
968+ CHECK_EQ (12345678901234e23f, StrtofTrimmed (vector, 23 ));
969+ CHECK_EQ (12345678901234e-1f , StrtofTrimmed (vector, -1 ));
970+ CHECK_EQ (12345678901234e-2f , StrtofTrimmed (vector, -2 ));
971+ CHECK_EQ (12345678901234e-5f , StrtofTrimmed (vector, -5 ));
972+ CHECK_EQ (12345678901234e-20f , StrtofTrimmed (vector, -20 ));
973+ CHECK_EQ (12345678901234e-22f , StrtofTrimmed (vector, -22 ));
974+ CHECK_EQ (12345678901234e-23f , StrtofTrimmed (vector, -23 ));
975+ CHECK_EQ (12345678901234e-25f , StrtofTrimmed (vector, -25 ));
976+ CHECK_EQ (12345678901234e-39f , StrtofTrimmed (vector, -39 ));
977+
978+ vector = StringToVector (" 123456789012345" );
979+ CHECK_EQ (123456789012345 .0f , StrtofTrimmed (vector, 0 ));
980+ CHECK_EQ (1234567890123450 .0f , StrtofTrimmed (vector, 1 ));
981+ CHECK_EQ (12345678901234500 .0f , StrtofTrimmed (vector, 2 ));
982+ CHECK_EQ (123456789012345e20f, StrtofTrimmed (vector, 20 ));
983+ CHECK_EQ (123456789012345e22f, StrtofTrimmed (vector, 22 ));
984+ CHECK_EQ (123456789012345e23f, StrtofTrimmed (vector, 23 ));
985+ CHECK_EQ (123456789012345e-1f , StrtofTrimmed (vector, -1 ));
986+ CHECK_EQ (123456789012345e-2f , StrtofTrimmed (vector, -2 ));
987+ CHECK_EQ (123456789012345e-5f , StrtofTrimmed (vector, -5 ));
988+ CHECK_EQ (123456789012345e-20f , StrtofTrimmed (vector, -20 ));
989+ CHECK_EQ (123456789012345e-22f , StrtofTrimmed (vector, -22 ));
990+ CHECK_EQ (123456789012345e-23f , StrtofTrimmed (vector, -23 ));
991+ CHECK_EQ (123456789012345e-25f , StrtofTrimmed (vector, -25 ));
992+ CHECK_EQ (123456789012345e-39f , StrtofTrimmed (vector, -39 ));
993+
994+ CHECK_EQ (0 .0f , StrtofTrimmedChar (" " , 1324 ));
995+ CHECK_EQ (0 .0f , StrtofTrimmedChar (" 2" , -324 ));
996+ CHECK_EQ (1e-45f , StrtofTrimmedChar (" 1" , -45 ));
997+ // It would be more readable to put non-zero literals on the left side (i.e.
998+ // CHECK_EQ(1e-46, StrtofChar("1", -45))), but then Gcc complains that
999+ // they are truncated to zero.
1000+ CHECK_EQ (0 .0f , StrtofTrimmedChar (" 1" , -46 ));
1001+ CHECK_EQ (0 .0f , StrtofTrimmedChar (" 1" , -47 ));
1002+ CHECK_EQ (1e-45f , StrtofTrimmedChar (" 1" , -45 ));
1003+ CHECK_EQ (1e-45f , StrtofTrimmedChar (" 8" , -46 ));
1004+
1005+ // It would be more readable to put the literals (and not Double::Infinity())
1006+ // on the left side (i.e. CHECK_EQ(3e38, StrtofChar("3", 38))), but then Gcc
1007+ // complains that the floating constant exceeds range of 'double'.
1008+ CHECK_EQ (Single::Infinity (), StrtofTrimmedChar (" 3" , 39 ));
1009+ CHECK_EQ (3e38f, StrtofTrimmedChar (" 3" , 38 ));
1010+ CHECK_EQ (3401e35f, StrtofTrimmedChar (" 3401" , 35 ));
1011+ CHECK_EQ (3401e34f, StrtofTrimmedChar (" 3401" , 34 ));
1012+ CHECK_EQ (34e37f, StrtofTrimmedChar (" 34" , 37 ));
1013+ CHECK_EQ (3 .4028234e+38f , StrtofTrimmedChar (" 34028235676" , 28 ));
1014+ CHECK_EQ (3 .4028234e+38f , StrtofTrimmedChar (" 34028235677" , 28 ));
1015+ CHECK_EQ (Single::Infinity (), StrtofTrimmedChar (" 34028235678" , 28 ));
1016+
1017+ // The following number is the result of 89255.0/1e-22. Both floating-point
1018+ // numbers can be accurately represented with doubles. However on Linux,x86
1019+ // the floating-point stack is set to 80bits and the double-rounding
1020+ // introduces an error.
1021+ CHECK_EQ (89255e-22f , StrtofTrimmedChar (" 89255" , -22 ));
1022+
1023+ // Boundary cases. Boundaries themselves should round to even.
1024+ //
1025+ // 0x4f012334 = 2166567936
1026+ // next: 2166568192
1027+ // boundary: 2166568064 should round down.
1028+ CHECK_EQ (2166567936 .0f , StrtofTrimmedChar (" 2166567936" , 0 ));
1029+ CHECK_EQ (2166568192 .0f , StrtofTrimmedChar (" 2166568192" , 0 ));
1030+ CHECK_EQ (2166567936 .0f , StrtofTrimmedChar (" 2166568064" , 0 ));
1031+ CHECK_EQ (2166567936 .0f , StrtofTrimmedChar (" 216656806399999" , -5 ));
1032+ CHECK_EQ (2166568192 .0f , StrtofTrimmedChar (" 216656806400001" , -5 ));
1033+ // Verify that we don't double round.
1034+ // Get the boundary of the boundary.
1035+ CHECK_EQ (2.1665680640000002384185791015625e9 , 2166568064.0 );
1036+ // Visual Studio gets this wrong and believes that these two numbers are the
1037+ // same doubles. We want to test our conversion and not the compiler. We
1038+ // therefore disable the check.
1039+ #ifndef _MSC_VER
1040+ CHECK (2.16656806400000023841857910156251e9 != 2166568064.0 );
1041+ #endif
1042+ CHECK_EQ (2166568192 .0f , StrtofTrimmedChar (" 21665680640000002384185791015625" , -22 ));
1043+
1044+ // 0x4fffffff = 8589934080
1045+ // next: 8589934592
1046+ // boundary: 8589934336 should round up.
1047+ CHECK_EQ (8589934592 .0f , StrtofTrimmedChar (" 8589934592" , 0 ));
1048+ CHECK_EQ (8589934592 .0f , StrtofTrimmedChar (" 8589934336" , 0 ));
1049+ CHECK_EQ (8589934080 .0f , StrtofTrimmedChar (" 858993433599999" , -5 ));
1050+ CHECK_EQ (8589934592 .0f , StrtofTrimmedChar (" 858993433600001" , -5 ));
1051+ // Verify that we don't double round.
1052+ // Get the boundary of the boundary.
1053+ // Visual Studio gets this wrong. To avoid failing tests because of a broken
1054+ // compiler we disable the following two tests. They were only testing the
1055+ // compiler. The real test is still active.
1056+ #ifndef _MSC_VER
1057+ CHECK_EQ (8.589934335999999523162841796875e+09 , 8589934336.0 );
1058+ CHECK (8.5899343359999995231628417968749e+09 != 8589934336.0 );
1059+ #endif
1060+ CHECK_EQ (8589934080 .0f , StrtofTrimmedChar (" 8589934335999999523162841796875" , -21 ));
1061+
1062+ // 0x4f000000 = 2147483648
1063+ // next: 2147483904
1064+ // boundary: 2147483776 should round down.
1065+ CHECK_EQ (2147483648 .0f , StrtofTrimmedChar (" 2147483648" , 0 ));
1066+ CHECK_EQ (2147483904 .0f , StrtofTrimmedChar (" 2147483904" , 0 ));
1067+ CHECK_EQ (2147483648 .0f , StrtofTrimmedChar (" 2147483776" , 0 ));
1068+ CHECK_EQ (2147483648 .0f , StrtofTrimmedChar (" 214748377599999" , -5 ));
1069+ CHECK_EQ (2147483904 .0f , StrtofTrimmedChar (" 214748377600001" , -5 ));
1070+ }
8791071
8801072static int CompareBignumToDiyFp (const Bignum& bignum_digits,
8811073 int bignum_exponent,
0 commit comments