Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(432)

Side by Side Diff: src/conversions.cc

Issue 3468003: Add bignum fall-back when the fast dtoa doesn't succeed. This removes Gay's d... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/bignum-dtoa.cc ('k') | src/dtoa.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/bignum-dtoa.cc ('k') | src/dtoa.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698