OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 | 647 |
648 if (nonzero_digit_dropped) { | 648 if (nonzero_digit_dropped) { |
649 buffer[buffer_pos++] = '1'; | 649 buffer[buffer_pos++] = '1'; |
650 exponent--; | 650 exponent--; |
651 } | 651 } |
652 | 652 |
653 ASSERT(buffer_pos < kBufferSize); | 653 ASSERT(buffer_pos < kBufferSize); |
654 buffer[buffer_pos] = '\0'; | 654 buffer[buffer_pos] = '\0'; |
655 | 655 |
656 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); | 656 double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); |
657 return sign? -converted: converted; | 657 return sign ? -converted : converted; |
658 } | 658 } |
659 | 659 |
660 | 660 |
661 double StringToDouble(String* str, int flags, double empty_string_val) { | 661 double StringToDouble(String* str, int flags, double empty_string_val) { |
662 StringShape shape(str); | 662 StringShape shape(str); |
663 if (shape.IsSequentialAscii()) { | 663 if (shape.IsSequentialAscii()) { |
664 const char* begin = SeqAsciiString::cast(str)->GetChars(); | 664 const char* begin = SeqAsciiString::cast(str)->GetChars(); |
665 const char* end = begin + str->length(); | 665 const char* end = begin + str->length(); |
666 return InternalStringToDouble(begin, end, flags, empty_string_val); | 666 return InternalStringToDouble(begin, end, flags, empty_string_val); |
667 } else if (shape.IsSequentialTwoByte()) { | 667 } else if (shape.IsSequentialTwoByte()) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 | 704 |
705 | 705 |
706 double StringToDouble(Vector<const char> str, | 706 double StringToDouble(Vector<const char> str, |
707 int flags, | 707 int flags, |
708 double empty_string_val) { | 708 double empty_string_val) { |
709 const char* end = str.start() + str.length(); | 709 const char* end = str.start() + str.length(); |
710 return InternalStringToDouble(str.start(), end, flags, empty_string_val); | 710 return InternalStringToDouble(str.start(), end, flags, empty_string_val); |
711 } | 711 } |
712 | 712 |
713 | 713 |
714 extern "C" char* dtoa(double d, int mode, int ndigits, | |
715 int* decpt, int* sign, char** rve); | |
716 | |
717 extern "C" void freedtoa(char* s); | |
718 | |
719 const char* DoubleToCString(double v, Vector<char> buffer) { | 714 const char* DoubleToCString(double v, Vector<char> buffer) { |
720 StringBuilder builder(buffer.start(), buffer.length()); | 715 StringBuilder builder(buffer.start(), buffer.length()); |
721 | 716 |
722 switch (fpclassify(v)) { | 717 switch (fpclassify(v)) { |
723 case FP_NAN: | 718 case FP_NAN: |
724 builder.AddString("NaN"); | 719 builder.AddString("NaN"); |
725 break; | 720 break; |
726 | 721 |
727 case FP_INFINITE: | 722 case FP_INFINITE: |
728 if (v < 0.0) { | 723 if (v < 0.0) { |
729 builder.AddString("-Infinity"); | 724 builder.AddString("-Infinity"); |
730 } else { | 725 } else { |
731 builder.AddString("Infinity"); | 726 builder.AddString("Infinity"); |
732 } | 727 } |
733 break; | 728 break; |
734 | 729 |
735 case FP_ZERO: | 730 case FP_ZERO: |
736 builder.AddCharacter('0'); | 731 builder.AddCharacter('0'); |
737 break; | 732 break; |
738 | 733 |
739 default: { | 734 default: { |
740 int decimal_point; | 735 int decimal_point; |
741 int sign; | 736 int sign; |
742 char* decimal_rep; | |
743 bool used_gay_dtoa = false; | |
744 const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1; | 737 const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1; |
745 char v8_dtoa_buffer[kV8DtoaBufferCapacity]; | 738 char decimal_rep[kV8DtoaBufferCapacity]; |
746 int length; | 739 int length; |
747 | 740 |
748 if (DoubleToAscii(v, DTOA_SHORTEST, 0, | 741 DoubleToAscii(v, DTOA_SHORTEST, 0, |
749 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), | 742 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
750 &sign, &length, &decimal_point)) { | 743 &sign, &length, &decimal_point); |
751 decimal_rep = v8_dtoa_buffer; | |
752 } else { | |
753 decimal_rep = dtoa(v, 0, 0, &decimal_point, &sign, NULL); | |
754 used_gay_dtoa = true; | |
755 length = StrLength(decimal_rep); | |
756 } | |
757 | 744 |
758 if (sign) builder.AddCharacter('-'); | 745 if (sign) builder.AddCharacter('-'); |
759 | 746 |
760 if (length <= decimal_point && decimal_point <= 21) { | 747 if (length <= decimal_point && decimal_point <= 21) { |
761 // ECMA-262 section 9.8.1 step 6. | 748 // ECMA-262 section 9.8.1 step 6. |
762 builder.AddString(decimal_rep); | 749 builder.AddString(decimal_rep); |
763 builder.AddPadding('0', decimal_point - length); | 750 builder.AddPadding('0', decimal_point - length); |
764 | 751 |
765 } else if (0 < decimal_point && decimal_point <= 21) { | 752 } else if (0 < decimal_point && decimal_point <= 21) { |
766 // ECMA-262 section 9.8.1 step 7. | 753 // ECMA-262 section 9.8.1 step 7. |
(...skipping 13 matching lines...) Expand all Loading... |
780 if (length != 1) { | 767 if (length != 1) { |
781 builder.AddCharacter('.'); | 768 builder.AddCharacter('.'); |
782 builder.AddString(decimal_rep + 1); | 769 builder.AddString(decimal_rep + 1); |
783 } | 770 } |
784 builder.AddCharacter('e'); | 771 builder.AddCharacter('e'); |
785 builder.AddCharacter((decimal_point >= 0) ? '+' : '-'); | 772 builder.AddCharacter((decimal_point >= 0) ? '+' : '-'); |
786 int exponent = decimal_point - 1; | 773 int exponent = decimal_point - 1; |
787 if (exponent < 0) exponent = -exponent; | 774 if (exponent < 0) exponent = -exponent; |
788 builder.AddFormatted("%d", exponent); | 775 builder.AddFormatted("%d", exponent); |
789 } | 776 } |
790 | |
791 if (used_gay_dtoa) freedtoa(decimal_rep); | |
792 } | 777 } |
793 } | 778 } |
794 return builder.Finalize(); | 779 return builder.Finalize(); |
795 } | 780 } |
796 | 781 |
797 | 782 |
798 const char* IntToCString(int n, Vector<char> buffer) { | 783 const char* IntToCString(int n, Vector<char> buffer) { |
799 bool negative = false; | 784 bool negative = false; |
800 if (n < 0) { | 785 if (n < 0) { |
801 // We must not negate the most negative int. | 786 // We must not negate the most negative int. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 } | 823 } |
839 | 824 |
840 // Find a sufficiently precise decimal representation of n. | 825 // Find a sufficiently precise decimal representation of n. |
841 int decimal_point; | 826 int decimal_point; |
842 int sign; | 827 int sign; |
843 // Add space for the '\0' byte. | 828 // Add space for the '\0' byte. |
844 const int kDecimalRepCapacity = | 829 const int kDecimalRepCapacity = |
845 kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1; | 830 kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1; |
846 char decimal_rep[kDecimalRepCapacity]; | 831 char decimal_rep[kDecimalRepCapacity]; |
847 int decimal_rep_length; | 832 int decimal_rep_length; |
848 bool status = DoubleToAscii(value, DTOA_FIXED, f, | 833 DoubleToAscii(value, DTOA_FIXED, f, |
849 Vector<char>(decimal_rep, kDecimalRepCapacity), | 834 Vector<char>(decimal_rep, kDecimalRepCapacity), |
850 &sign, &decimal_rep_length, &decimal_point); | 835 &sign, &decimal_rep_length, &decimal_point); |
851 USE(status); | |
852 ASSERT(status); | |
853 | 836 |
854 // Create a representation that is padded with zeros if needed. | 837 // Create a representation that is padded with zeros if needed. |
855 int zero_prefix_length = 0; | 838 int zero_prefix_length = 0; |
856 int zero_postfix_length = 0; | 839 int zero_postfix_length = 0; |
857 | 840 |
858 if (decimal_point <= 0) { | 841 if (decimal_point <= 0) { |
859 zero_prefix_length = -decimal_point + 1; | 842 zero_prefix_length = -decimal_point + 1; |
860 decimal_point = 1; | 843 decimal_point = 1; |
861 } | 844 } |
862 | 845 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 | 911 |
929 bool negative = false; | 912 bool negative = false; |
930 if (value < 0) { | 913 if (value < 0) { |
931 value = -value; | 914 value = -value; |
932 negative = true; | 915 negative = true; |
933 } | 916 } |
934 | 917 |
935 // Find a sufficiently precise decimal representation of n. | 918 // Find a sufficiently precise decimal representation of n. |
936 int decimal_point; | 919 int decimal_point; |
937 int sign; | 920 int sign; |
938 char* decimal_rep = NULL; | |
939 bool used_gay_dtoa = false; | |
940 // f corresponds to the digits after the point. There is always one digit | 921 // f corresponds to the digits after the point. There is always one digit |
941 // before the point. The number of requested_digits equals hence f + 1. | 922 // before the point. The number of requested_digits equals hence f + 1. |
942 // And we have to add one character for the null-terminator. | 923 // And we have to add one character for the null-terminator. |
943 const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; | 924 const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; |
944 // Make sure that the buffer is big enough, even if we fall back to the | 925 // Make sure that the buffer is big enough, even if we fall back to the |
945 // shortest representation (which happens when f equals -1). | 926 // shortest representation (which happens when f equals -1). |
946 ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); | 927 ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); |
947 char v8_dtoa_buffer[kV8DtoaBufferCapacity]; | 928 char decimal_rep[kV8DtoaBufferCapacity]; |
948 int decimal_rep_length; | 929 int decimal_rep_length; |
949 | 930 |
950 if (f == -1) { | 931 if (f == -1) { |
951 if (DoubleToAscii(value, DTOA_SHORTEST, 0, | 932 DoubleToAscii(value, DTOA_SHORTEST, 0, |
952 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), | 933 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
953 &sign, &decimal_rep_length, &decimal_point)) { | 934 &sign, &decimal_rep_length, &decimal_point); |
954 f = decimal_rep_length - 1; | 935 f = decimal_rep_length - 1; |
955 decimal_rep = v8_dtoa_buffer; | |
956 } else { | |
957 decimal_rep = dtoa(value, 0, 0, &decimal_point, &sign, NULL); | |
958 decimal_rep_length = StrLength(decimal_rep); | |
959 f = decimal_rep_length - 1; | |
960 used_gay_dtoa = true; | |
961 } | |
962 } else { | 936 } else { |
963 if (DoubleToAscii(value, DTOA_PRECISION, f + 1, | 937 DoubleToAscii(value, DTOA_PRECISION, f + 1, |
964 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), | 938 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
965 &sign, &decimal_rep_length, &decimal_point)) { | 939 &sign, &decimal_rep_length, &decimal_point); |
966 decimal_rep = v8_dtoa_buffer; | |
967 } else { | |
968 decimal_rep = dtoa(value, 2, f + 1, &decimal_point, &sign, NULL); | |
969 decimal_rep_length = StrLength(decimal_rep); | |
970 used_gay_dtoa = true; | |
971 } | |
972 } | 940 } |
973 ASSERT(decimal_rep_length > 0); | 941 ASSERT(decimal_rep_length > 0); |
974 ASSERT(decimal_rep_length <= f + 1); | 942 ASSERT(decimal_rep_length <= f + 1); |
975 | 943 |
976 int exponent = decimal_point - 1; | 944 int exponent = decimal_point - 1; |
977 char* result = | 945 char* result = |
978 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); | 946 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); |
979 | 947 |
980 if (used_gay_dtoa) { | |
981 freedtoa(decimal_rep); | |
982 } | |
983 | |
984 return result; | 948 return result; |
985 } | 949 } |
986 | 950 |
987 | 951 |
988 char* DoubleToPrecisionCString(double value, int p) { | 952 char* DoubleToPrecisionCString(double value, int p) { |
989 const int kMinimalDigits = 1; | 953 const int kMinimalDigits = 1; |
990 const int kMaximalDigits = 21; | 954 const int kMaximalDigits = 21; |
991 ASSERT(p >= kMinimalDigits && p <= kMaximalDigits); | 955 ASSERT(p >= kMinimalDigits && p <= kMaximalDigits); |
992 USE(kMinimalDigits); | 956 USE(kMinimalDigits); |
993 | 957 |
994 bool negative = false; | 958 bool negative = false; |
995 if (value < 0) { | 959 if (value < 0) { |
996 value = -value; | 960 value = -value; |
997 negative = true; | 961 negative = true; |
998 } | 962 } |
999 | 963 |
1000 // Find a sufficiently precise decimal representation of n. | 964 // Find a sufficiently precise decimal representation of n. |
1001 int decimal_point; | 965 int decimal_point; |
1002 int sign; | 966 int sign; |
1003 char* decimal_rep = NULL; | |
1004 bool used_gay_dtoa = false; | |
1005 // Add one for the terminating null character. | 967 // Add one for the terminating null character. |
1006 const int kV8DtoaBufferCapacity = kMaximalDigits + 1; | 968 const int kV8DtoaBufferCapacity = kMaximalDigits + 1; |
1007 char v8_dtoa_buffer[kV8DtoaBufferCapacity]; | 969 char decimal_rep[kV8DtoaBufferCapacity]; |
1008 int decimal_rep_length; | 970 int decimal_rep_length; |
1009 | 971 |
1010 if (DoubleToAscii(value, DTOA_PRECISION, p, | 972 DoubleToAscii(value, DTOA_PRECISION, p, |
1011 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), | 973 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
1012 &sign, &decimal_rep_length, &decimal_point)) { | 974 &sign, &decimal_rep_length, &decimal_point); |
1013 decimal_rep = v8_dtoa_buffer; | |
1014 } else { | |
1015 decimal_rep = dtoa(value, 2, p, &decimal_point, &sign, NULL); | |
1016 decimal_rep_length = StrLength(decimal_rep); | |
1017 used_gay_dtoa = true; | |
1018 } | |
1019 ASSERT(decimal_rep_length <= p); | 975 ASSERT(decimal_rep_length <= p); |
1020 | 976 |
1021 int exponent = decimal_point - 1; | 977 int exponent = decimal_point - 1; |
1022 | 978 |
1023 char* result = NULL; | 979 char* result = NULL; |
1024 | 980 |
1025 if (exponent < -6 || exponent >= p) { | 981 if (exponent < -6 || exponent >= p) { |
1026 result = | 982 result = |
1027 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); | 983 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); |
1028 } else { | 984 } else { |
(...skipping 23 matching lines...) Expand all Loading... |
1052 const int len = StrLength(decimal_rep + decimal_point); | 1008 const int len = StrLength(decimal_rep + decimal_point); |
1053 const int n = Min(len, p - (builder.position() - extra)); | 1009 const int n = Min(len, p - (builder.position() - extra)); |
1054 builder.AddSubstring(decimal_rep + decimal_point, n); | 1010 builder.AddSubstring(decimal_rep + decimal_point, n); |
1055 } | 1011 } |
1056 builder.AddPadding('0', extra + (p - builder.position())); | 1012 builder.AddPadding('0', extra + (p - builder.position())); |
1057 } | 1013 } |
1058 } | 1014 } |
1059 result = builder.Finalize(); | 1015 result = builder.Finalize(); |
1060 } | 1016 } |
1061 | 1017 |
1062 if (used_gay_dtoa) { | |
1063 freedtoa(decimal_rep); | |
1064 } | |
1065 return result; | 1018 return result; |
1066 } | 1019 } |
1067 | 1020 |
1068 | 1021 |
1069 char* DoubleToRadixCString(double value, int radix) { | 1022 char* DoubleToRadixCString(double value, int radix) { |
1070 ASSERT(radix >= 2 && radix <= 36); | 1023 ASSERT(radix >= 2 && radix <= 36); |
1071 | 1024 |
1072 // Character array used for conversion. | 1025 // Character array used for conversion. |
1073 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; | 1026 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
1074 | 1027 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1131 // Allocate result and fill in the parts. | 1084 // Allocate result and fill in the parts. |
1132 StringBuilder builder(result_size + 1); | 1085 StringBuilder builder(result_size + 1); |
1133 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); | 1086 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); |
1134 if (decimal_pos > 0) builder.AddCharacter('.'); | 1087 if (decimal_pos > 0) builder.AddCharacter('.'); |
1135 builder.AddSubstring(decimal_buffer, decimal_pos); | 1088 builder.AddSubstring(decimal_buffer, decimal_pos); |
1136 return builder.Finalize(); | 1089 return builder.Finalize(); |
1137 } | 1090 } |
1138 | 1091 |
1139 | 1092 |
1140 } } // namespace v8::internal | 1093 } } // namespace v8::internal |
OLD | NEW |