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 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 | 942 |
943 builder.AddCharacter('e'); | 943 builder.AddCharacter('e'); |
944 builder.AddCharacter(negative_exponent ? '-' : '+'); | 944 builder.AddCharacter(negative_exponent ? '-' : '+'); |
945 builder.AddFormatted("%d", exponent); | 945 builder.AddFormatted("%d", exponent); |
946 return builder.Finalize(); | 946 return builder.Finalize(); |
947 } | 947 } |
948 | 948 |
949 | 949 |
950 | 950 |
951 char* DoubleToExponentialCString(double value, int f) { | 951 char* DoubleToExponentialCString(double value, int f) { |
| 952 const int kMaxDigitsAfterPoint = 20; |
952 // f might be -1 to signal that f was undefined in JavaScript. | 953 // f might be -1 to signal that f was undefined in JavaScript. |
953 ASSERT(f >= -1 && f <= 20); | 954 ASSERT(f >= -1 && f <= kMaxDigitsAfterPoint); |
954 | 955 |
955 bool negative = false; | 956 bool negative = false; |
956 if (value < 0) { | 957 if (value < 0) { |
957 value = -value; | 958 value = -value; |
958 negative = true; | 959 negative = true; |
959 } | 960 } |
960 | 961 |
961 // Find a sufficiently precise decimal representation of n. | 962 // Find a sufficiently precise decimal representation of n. |
962 int decimal_point; | 963 int decimal_point; |
963 int sign; | 964 int sign; |
964 char* decimal_rep = NULL; | 965 char* decimal_rep = NULL; |
| 966 bool used_gay_dtoa = false; |
| 967 // f corresponds to the digits after the point. There is always one digit |
| 968 // before the point. The number of requested_digits equals hence f + 1. |
| 969 // And we have to add one character for the null-terminator. |
| 970 const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; |
| 971 // Make sure that the buffer is big enough, even if we fall back to the |
| 972 // shortest representation (which happens when f equals -1). |
| 973 ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); |
| 974 char v8_dtoa_buffer[kV8DtoaBufferCapacity]; |
| 975 int decimal_rep_length; |
| 976 |
965 if (f == -1) { | 977 if (f == -1) { |
966 decimal_rep = dtoa(value, 0, 0, &decimal_point, &sign, NULL); | 978 if (DoubleToAscii(value, DTOA_SHORTEST, 0, |
967 f = StrLength(decimal_rep) - 1; | 979 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), |
| 980 &sign, &decimal_rep_length, &decimal_point)) { |
| 981 f = decimal_rep_length - 1; |
| 982 decimal_rep = v8_dtoa_buffer; |
| 983 } else { |
| 984 decimal_rep = dtoa(value, 0, 0, &decimal_point, &sign, NULL); |
| 985 decimal_rep_length = StrLength(decimal_rep); |
| 986 f = decimal_rep_length - 1; |
| 987 used_gay_dtoa = true; |
| 988 } |
968 } else { | 989 } else { |
969 decimal_rep = dtoa(value, 2, f + 1, &decimal_point, &sign, NULL); | 990 if (DoubleToAscii(value, DTOA_PRECISION, f + 1, |
| 991 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), |
| 992 &sign, &decimal_rep_length, &decimal_point)) { |
| 993 decimal_rep = v8_dtoa_buffer; |
| 994 } else { |
| 995 decimal_rep = dtoa(value, 2, f + 1, &decimal_point, &sign, NULL); |
| 996 decimal_rep_length = StrLength(decimal_rep); |
| 997 used_gay_dtoa = true; |
| 998 } |
970 } | 999 } |
971 int decimal_rep_length = StrLength(decimal_rep); | |
972 ASSERT(decimal_rep_length > 0); | 1000 ASSERT(decimal_rep_length > 0); |
973 ASSERT(decimal_rep_length <= f + 1); | 1001 ASSERT(decimal_rep_length <= f + 1); |
974 USE(decimal_rep_length); | |
975 | 1002 |
976 int exponent = decimal_point - 1; | 1003 int exponent = decimal_point - 1; |
977 char* result = | 1004 char* result = |
978 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); | 1005 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); |
979 | 1006 |
980 freedtoa(decimal_rep); | 1007 if (used_gay_dtoa) { |
| 1008 freedtoa(decimal_rep); |
| 1009 } |
981 | 1010 |
982 return result; | 1011 return result; |
983 } | 1012 } |
984 | 1013 |
985 | 1014 |
986 char* DoubleToPrecisionCString(double value, int p) { | 1015 char* DoubleToPrecisionCString(double value, int p) { |
987 ASSERT(p >= 1 && p <= 21); | 1016 const int kMinimalDigits = 1; |
| 1017 const int kMaximalDigits = 21; |
| 1018 ASSERT(p >= kMinimalDigits && p <= kMaximalDigits); |
| 1019 USE(kMinimalDigits); |
988 | 1020 |
989 bool negative = false; | 1021 bool negative = false; |
990 if (value < 0) { | 1022 if (value < 0) { |
991 value = -value; | 1023 value = -value; |
992 negative = true; | 1024 negative = true; |
993 } | 1025 } |
994 | 1026 |
995 // Find a sufficiently precise decimal representation of n. | 1027 // Find a sufficiently precise decimal representation of n. |
996 int decimal_point; | 1028 int decimal_point; |
997 int sign; | 1029 int sign; |
998 char* decimal_rep = dtoa(value, 2, p, &decimal_point, &sign, NULL); | 1030 char* decimal_rep = NULL; |
999 int decimal_rep_length = StrLength(decimal_rep); | 1031 bool used_gay_dtoa = false; |
| 1032 // Add one for the terminating null character. |
| 1033 const int kV8DtoaBufferCapacity = kMaximalDigits + 1; |
| 1034 char v8_dtoa_buffer[kV8DtoaBufferCapacity]; |
| 1035 int decimal_rep_length; |
| 1036 |
| 1037 if (DoubleToAscii(value, DTOA_PRECISION, p, |
| 1038 Vector<char>(v8_dtoa_buffer, kV8DtoaBufferCapacity), |
| 1039 &sign, &decimal_rep_length, &decimal_point)) { |
| 1040 decimal_rep = v8_dtoa_buffer; |
| 1041 } else { |
| 1042 decimal_rep = dtoa(value, 2, p, &decimal_point, &sign, NULL); |
| 1043 decimal_rep_length = StrLength(decimal_rep); |
| 1044 used_gay_dtoa = true; |
| 1045 } |
1000 ASSERT(decimal_rep_length <= p); | 1046 ASSERT(decimal_rep_length <= p); |
1001 | 1047 |
1002 int exponent = decimal_point - 1; | 1048 int exponent = decimal_point - 1; |
1003 | 1049 |
1004 char* result = NULL; | 1050 char* result = NULL; |
1005 | 1051 |
1006 if (exponent < -6 || exponent >= p) { | 1052 if (exponent < -6 || exponent >= p) { |
1007 result = | 1053 result = |
1008 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); | 1054 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); |
1009 } else { | 1055 } else { |
(...skipping 23 matching lines...) Expand all Loading... |
1033 const int len = StrLength(decimal_rep + decimal_point); | 1079 const int len = StrLength(decimal_rep + decimal_point); |
1034 const int n = Min(len, p - (builder.position() - extra)); | 1080 const int n = Min(len, p - (builder.position() - extra)); |
1035 builder.AddSubstring(decimal_rep + decimal_point, n); | 1081 builder.AddSubstring(decimal_rep + decimal_point, n); |
1036 } | 1082 } |
1037 builder.AddPadding('0', extra + (p - builder.position())); | 1083 builder.AddPadding('0', extra + (p - builder.position())); |
1038 } | 1084 } |
1039 } | 1085 } |
1040 result = builder.Finalize(); | 1086 result = builder.Finalize(); |
1041 } | 1087 } |
1042 | 1088 |
1043 freedtoa(decimal_rep); | 1089 if (used_gay_dtoa) { |
| 1090 freedtoa(decimal_rep); |
| 1091 } |
1044 return result; | 1092 return result; |
1045 } | 1093 } |
1046 | 1094 |
1047 | 1095 |
1048 char* DoubleToRadixCString(double value, int radix) { | 1096 char* DoubleToRadixCString(double value, int radix) { |
1049 ASSERT(radix >= 2 && radix <= 36); | 1097 ASSERT(radix >= 2 && radix <= 36); |
1050 | 1098 |
1051 // Character array used for conversion. | 1099 // Character array used for conversion. |
1052 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; | 1100 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
1053 | 1101 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 // Allocate result and fill in the parts. | 1158 // Allocate result and fill in the parts. |
1111 StringBuilder builder(result_size + 1); | 1159 StringBuilder builder(result_size + 1); |
1112 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); | 1160 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); |
1113 if (decimal_pos > 0) builder.AddCharacter('.'); | 1161 if (decimal_pos > 0) builder.AddCharacter('.'); |
1114 builder.AddSubstring(decimal_buffer, decimal_pos); | 1162 builder.AddSubstring(decimal_buffer, decimal_pos); |
1115 return builder.Finalize(); | 1163 return builder.Finalize(); |
1116 } | 1164 } |
1117 | 1165 |
1118 | 1166 |
1119 } } // namespace v8::internal | 1167 } } // namespace v8::internal |
OLD | NEW |