OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/strings/string_number_conversions.h" | 5 #include "base/strings/string_number_conversions.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <limits.h> | 8 #include <limits.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <stdint.h> | 10 #include <stdint.h> |
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
798 } | 798 } |
799 | 799 |
800 TEST(StringNumberConversionsTest, HexEncode) { | 800 TEST(StringNumberConversionsTest, HexEncode) { |
801 std::string hex(HexEncode(NULL, 0)); | 801 std::string hex(HexEncode(NULL, 0)); |
802 EXPECT_EQ(hex.length(), 0U); | 802 EXPECT_EQ(hex.length(), 0U); |
803 unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81}; | 803 unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81}; |
804 hex = HexEncode(bytes, sizeof(bytes)); | 804 hex = HexEncode(bytes, sizeof(bytes)); |
805 EXPECT_EQ(hex.compare("01FF02FE038081"), 0); | 805 EXPECT_EQ(hex.compare("01FF02FE038081"), 0); |
806 } | 806 } |
807 | 807 |
808 // http://www.exploringbinary.com/converting-floating-point-numbers-to-binary-st rings-in-c/ | |
Nico
2016/06/08 00:45:09
that doesn't say anything about license or "ok to
scottmg
2016/06/08 02:28:18
Hmm, true. I'll see if I can find something simila
| |
809 // by Rick Regan. | |
810 std::string FpToBin(double fp) { | |
811 double fp_int; | |
812 double fp_frac = modf(fp, &fp_int); | |
813 | |
814 std::string result; | |
815 if (fp_int != 0) { | |
816 std::string integral; | |
817 do { | |
818 integral += '0' + static_cast<int>(fmod(fp_int, 2)); | |
819 fp_int = floor(fp_int / 2); | |
820 } while (fp_int > 0); | |
821 std::reverse(integral.begin(), integral.end()); | |
822 result += integral; | |
823 } else { | |
824 result += "0"; | |
825 } | |
826 | |
827 result += "."; | |
828 | |
829 if (fp_frac != 0) { | |
830 std::string fractional; | |
831 while (fp_frac > 0) { | |
832 fp_frac *= 2; | |
833 double integral_part; | |
834 fp_frac = modf(fp_frac, &integral_part); | |
835 fractional += '0' + static_cast<int>(integral_part); | |
836 } | |
837 result += fractional; | |
838 } else { | |
839 result += "0"; | |
840 } | |
841 | |
842 return result; | |
843 } | |
844 | |
845 TEST(StringNumberConversionsTest, TestFpToBin) { | |
846 EXPECT_EQ(FpToBin(16), "10000.0"); | |
847 EXPECT_EQ(FpToBin(0.00390625), "0.00000001"); | |
848 EXPECT_EQ(FpToBin(25), "11001.0"); | |
849 EXPECT_EQ(FpToBin(0.1), | |
850 "0.0001100110011001100110011001100110011001100110011001101"); | |
851 EXPECT_EQ(FpToBin(0.6), | |
852 "0.10011001100110011001100110011001100110011001100110011"); | |
853 } | |
854 | |
855 // Test cases of known-bad strtod conversions that motivated the use of dmg_fp. | |
856 // See https://bugs.chromium.org/p/chromium/issues/detail?id=593512. | |
857 TEST(StringNumberConversionsTest, StrtodFailures) { | |
858 static const struct { | |
859 const char* input; | |
860 const char* expected; | |
861 } cases[] = { | |
862 // http://www.exploringbinary.com/incorrectly-rounded-conversions-in-visua l-c-plus-plus/ | |
863 {"9214843084008499", | |
864 "100000101111001101100111011000101011101110110000110100.0"}, | |
Nico
2016/06/08 00:45:09
could we use hexfloats for the expecteds instead?
scottmg
2016/06/08 02:28:18
VS doesn't seem to support hex floating point lite
scottmg
2016/06/08 02:36:04
No such luck.
d:\src\x>type fp.c
#include <stdio.
| |
865 {"0.500000000000000166533453693773481063544750213623046875", | |
866 "0.1000000000000000000000000000000000000000000000000001"}, | |
867 {"30078505129381147446200", | |
868 "1100101111010001111000111001001110001101100000010000100000000000000" | |
869 "00000000.0"}, | |
870 {"1777820000000000000001", | |
871 "1100000011000000011010101101110101101001011100011111000000000000000" | |
872 "0000.0"}, | |
873 {"0." | |
874 "500000000000000166547006220929549868969843373633921146392822265625", | |
875 "0.1000000000000000000000000000000000000000000000000001"}, | |
876 {"0." | |
877 "50000000000000016656055874808561867439493653364479541778564453125", | |
878 "0.1000000000000000000000000000000000000000000000000001"}, | |
879 {"0.3932922657273", | |
880 "0.01100100101011101100110101001011000100011000100011101"}, | |
881 | |
882 // http://www.exploringbinary.com/incorrectly-rounded-conversions-in-gcc-a nd-glibc/ | |
883 {"0.500000000000000166533453693773481063544750213623046875", | |
884 "0.1000000000000000000000000000000000000000000000000001"}, | |
885 {"3.518437208883201171875e13", | |
886 "1000000000000000000000000000000000000000000000.000001"}, | |
887 {"62.5364939768271845828", | |
888 "111110.100010010101011110101011010101001111100101001"}, | |
889 {"8.10109172351e-10", | |
890 "0." | |
891 "0000000000000000000000000000001101111010101110010111010111011110000" | |
892 "11111101000011"}, | |
893 {"1.50000000000000011102230246251565404236316680908203125", "1.1"}, | |
894 {"9007199254740991.4999999999999999999999999999999995", | |
895 "11111111111111111111111111111111111111111111111111111.0"}, | |
896 | |
897 // http://www.exploringbinary.com/incorrect-decimal-to-floating-point-conv ersion-in-sqlite/ | |
898 {"1e-23", | |
899 /* 0x1.82db34012b251p-77 */ "0." | |
900 "0000000000000000000000000000000000000000000" | |
901 "0000000000000000000000000000000001100000101" | |
902 "101101100110100000000010010101100100101000" | |
903 "1"}, | |
904 {"8.533e+68", | |
905 /* 0x1.fa69165a8eea2p+228 */ "111111010011010010001011001011010100011101" | |
906 "110101000100000000000000000000000000000000" | |
907 "000000000000000000000000000000000000000000" | |
908 "000000000000000000000000000000000000000000" | |
909 "000000000000000000000000000000000000000000" | |
910 "0000000000000000000.0"}, | |
911 {"4.1006e-184", | |
912 /* 0x1.be0d1c7ea60c9p-610 */ "0." | |
913 "000000000000000000000000000000000000000000" | |
914 "000000000000000000000000000000000000000000" | |
915 "000000000000000000000000000000000000000000" | |
916 "000000000000000000000000000000000000000000" | |
917 "000000000000000000000000000000000000000000" | |
918 "000000000000000000000000000000000000000000" | |
919 "000000000000000000000000000000000000000000" | |
920 "000000000000000000000000000000000000000000" | |
921 "000000000000000000000000000000000000000000" | |
922 "000000000000000000000000000000000000000000" | |
923 "000000000000000000000000000000000000000000" | |
924 "000000000000000000000000000000000000000000" | |
925 "000000000000000000000000000000000000000000" | |
926 "000000000000000000000000000000000000000000" | |
927 "000000000000000000000110111110000011010001" | |
928 "11000111111010100110000011001001"}, | |
929 {"9.998e+307", | |
930 /* 0x1.1cc0a350ca87bp+1023 */ "10001110011000000101000110101000011001010" | |
931 "10000111101100000000000000000000000000000" | |
932 "00000000000000000000000000000000000000000" | |
933 "00000000000000000000000000000000000000000" | |
934 "00000000000000000000000000000000000000000" | |
935 "00000000000000000000000000000000000000000" | |
936 "00000000000000000000000000000000000000000" | |
937 "00000000000000000000000000000000000000000" | |
938 "00000000000000000000000000000000000000000" | |
939 "00000000000000000000000000000000000000000" | |
940 "00000000000000000000000000000000000000000" | |
941 "00000000000000000000000000000000000000000" | |
942 "00000000000000000000000000000000000000000" | |
943 "00000000000000000000000000000000000000000" | |
944 "00000000000000000000000000000000000000000" | |
945 "00000000000000000000000000000000000000000" | |
946 "00000000000000000000000000000000000000000" | |
947 "00000000000000000000000000000000000000000" | |
948 "00000000000000000000000000000000000000000" | |
949 "00000000000000000000000000000000000000000" | |
950 "00000000000000000000000000000000000000000" | |
951 "00000000000000000000000000000000000000000" | |
952 "00000000000000000000000000000000000000000" | |
953 "00000000000000000000000000000000000000000" | |
954 "0000000000000000000000000000000000000000." | |
955 "0"}, | |
956 {"9.9538452227e-280", | |
957 /* 0x1.2117ae45cde43p-927 */ "0." | |
958 "000000000000000000000000000000000000000000" | |
959 "000000000000000000000000000000000000000000" | |
960 "000000000000000000000000000000000000000000" | |
961 "000000000000000000000000000000000000000000" | |
962 "000000000000000000000000000000000000000000" | |
963 "000000000000000000000000000000000000000000" | |
964 "000000000000000000000000000000000000000000" | |
965 "000000000000000000000000000000000000000000" | |
966 "000000000000000000000000000000000000000000" | |
967 "000000000000000000000000000000000000000000" | |
968 "000000000000000000000000000000000000000000" | |
969 "000000000000000000000000000000000000000000" | |
970 "000000000000000000000000000000000000000000" | |
971 "000000000000000000000000000000000000000000" | |
972 "000000000000000000000000000000000000000000" | |
973 "000000000000000000000000000000000000000000" | |
974 "000000000000000000000000000000000000000000" | |
975 "000000000000000000000000000000000000000000" | |
976 "000000000000000000000000000000000000000000" | |
977 "000000000000000000000000000000000000000000" | |
978 "000000000000000000000000000000000000000000" | |
979 "000000000000000000000000000000000000000000" | |
980 "001001000010001011110101110010001011100110" | |
981 "1111001000011"}, | |
982 {"6.47660115e-260", | |
983 /* 0x1.fdd9e333badadp-862 */ "0." | |
984 "000000000000000000000000000000000000000000" | |
985 "000000000000000000000000000000000000000000" | |
986 "000000000000000000000000000000000000000000" | |
987 "000000000000000000000000000000000000000000" | |
988 "000000000000000000000000000000000000000000" | |
989 "000000000000000000000000000000000000000000" | |
990 "000000000000000000000000000000000000000000" | |
991 "000000000000000000000000000000000000000000" | |
992 "000000000000000000000000000000000000000000" | |
993 "000000000000000000000000000000000000000000" | |
994 "000000000000000000000000000000000000000000" | |
995 "000000000000000000000000000000000000000000" | |
996 "000000000000000000000000000000000000000000" | |
997 "000000000000000000000000000000000000000000" | |
998 "000000000000000000000000000000000000000000" | |
999 "000000000000000000000000000000000000000000" | |
1000 "000000000000000000000000000000000000000000" | |
1001 "000000000000000000000000000000000000000000" | |
1002 "000000000000000000000000000000000000000000" | |
1003 "000000000000000000000000000000000000000000" | |
1004 "000000000000000000000111111101110110011110" | |
1005 "00110011001110111010110110101101"}, | |
1006 {"7.4e+47", | |
1007 /* 0x1.033d7eca0adefp+159 */ "100000011001111010111111011001010000010101" | |
1008 "101111011110000000000000000000000000000000" | |
1009 "000000000000000000000000000000000000000000" | |
1010 "0000000000000000000000000000000000.0"}, | |
1011 {"5.92e+48", | |
1012 /* 0x1.033d7eca0adefp+162 */ "100000011001111010111111011001010000010101" | |
1013 "101111011110000000000000000000000000000000" | |
1014 "000000000000000000000000000000000000000000" | |
1015 "0000000000000000000000000000000000000.0"}, | |
1016 {"7.35e+66", | |
1017 /* 0x1.172b70eababa9p+222 */ "100010111001010110111000011101010101110101" | |
1018 "011101010010000000000000000000000000000000" | |
1019 "000000000000000000000000000000000000000000" | |
1020 "000000000000000000000000000000000000000000" | |
1021 "000000000000000000000000000000000000000000" | |
1022 "0000000000000.0"}, | |
1023 {"8.32116e+55", | |
1024 /* 0x1.b2628393e02cdp+185 */ "110110010011000101000001110010011111000000" | |
1025 "010110011010000000000000000000000000000000" | |
1026 "000000000000000000000000000000000000000000" | |
1027 "000000000000000000000000000000000000000000" | |
1028 "000000000000000000.0"}, | |
1029 }; | |
1030 | |
1031 for (const auto& test : cases) { | |
1032 double output; | |
1033 EXPECT_TRUE(StringToDouble(test.input, &output)); | |
1034 EXPECT_EQ(FpToBin(output), test.expected); | |
1035 } | |
1036 } | |
1037 | |
808 } // namespace base | 1038 } // namespace base |
OLD | NEW |