Chromium Code Reviews| 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 |