Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
double_conversion.cc
Go to the documentation of this file.
1// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
6
7#include "../../third_party/double-conversion/src/double-conversion.h"
8
9#include "vm/exceptions.h"
10#include "vm/globals.h"
11#include "vm/object.h"
12
13namespace dart {
14
15static constexpr char kExponentChar = 'e';
16static constexpr const char* kInfinitySymbol = "Infinity";
17static constexpr const char* kNaNSymbol = "NaN";
18
19void DoubleToCString(double d, char* buffer, int buffer_size) {
20 const int kDecimalLow = -6;
21 const int kDecimalHigh = 21;
22
23 // The output contains the sign, at most kDecimalHigh - 1 digits,
24 // the decimal point followed by a 0 plus the \0.
25 ASSERT(buffer_size >= 1 + (kDecimalHigh - 1) + 1 + 1 + 1);
26 // Or it contains the sign, a 0, the decimal point, kDecimalLow '0's,
27 // 17 digits (the precision needed for doubles), plus the \0.
28 ASSERT(buffer_size >= 1 + 1 + 1 + kDecimalLow + 17 + 1);
29 // Alternatively it contains a sign, at most 17 digits (precision needed for
30 // any double), the decimal point, the exponent character, the exponent's
31 // sign, at most three exponent digits, plus the \0.
32 ASSERT(buffer_size >= 1 + 17 + 1 + 1 + 1 + 3 + 1);
33
34 const int kConversionFlags =
39
41 kConversionFlags, kInfinitySymbol, kNaNSymbol, kExponentChar, kDecimalLow,
42 kDecimalHigh, 0,
43 0); // Last two values are ignored in shortest mode.
44
46 bool status = converter.ToShortest(d, &builder);
47 ASSERT(status);
48 char* result = builder.Finalize();
50}
51
52StringPtr DoubleToStringAsFixed(double d, int fraction_digits) {
53 const int kMinFractionDigits = 0;
54 const int kMaxFractionDigits = 20;
55 const int kMaxDigitsBeforePoint = 20;
56 // The boundaries are exclusive.
57 const double kLowerBoundary = -1e21;
58 const double kUpperBoundary = 1e21;
59 // TODO(floitsch): remove the UNIQUE_ZERO flag when the test is updated.
60 const int kConversionFlags =
62 const int kBufferSize = 128;
63
64 USE(kMaxDigitsBeforePoint);
65 USE(kMaxFractionDigits);
66 USE(kLowerBoundary);
67 USE(kUpperBoundary);
68 USE(kMinFractionDigits);
69 USE(kMaxFractionDigits);
70 // The output contains the sign, at most kMaxDigitsBeforePoint digits,
71 // the decimal point followed by at most fraction_digits digits plus the \0.
72 ASSERT(kBufferSize >= 1 + kMaxDigitsBeforePoint + 1 + kMaxFractionDigits + 1);
73
74 ASSERT(kLowerBoundary < d && d < kUpperBoundary);
75
76 ASSERT(kMinFractionDigits <= fraction_digits &&
77 fraction_digits <= kMaxFractionDigits);
78
80 kConversionFlags, kInfinitySymbol, kNaNSymbol, kExponentChar, 0, 0, 0,
81 0); // Last four values are ignored in fixed mode.
82
83 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize);
84 buffer[kBufferSize - 1] = '\0';
86 bool status = converter.ToFixed(d, fraction_digits, &builder);
87 ASSERT(status);
88 return String::New(builder.Finalize());
89}
90
91StringPtr DoubleToStringAsExponential(double d, int fraction_digits) {
92 const int kMinFractionDigits = -1; // -1 represents shortest mode.
93 const int kMaxFractionDigits = 20;
94 const int kConversionFlags =
96 const int kBufferSize = 128;
97
98 USE(kMinFractionDigits);
99 USE(kMaxFractionDigits);
100 // The output contains the sign, at most 1 digits, the decimal point followed
101 // by at most kMaxFractionDigits digits, the exponent-character, the
102 // exponent-sign and three exponent digits plus \0.
103 ASSERT(kBufferSize >= 1 + 1 + kMaxFractionDigits + 1 + 1 + 3 + 1);
104
105 ASSERT(kMinFractionDigits <= fraction_digits &&
106 fraction_digits <= kMaxFractionDigits);
107
109 kConversionFlags, kInfinitySymbol, kNaNSymbol, kExponentChar, 0, 0, 0,
110 0); // Last four values are ignored in exponential mode.
111
112 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize);
113 buffer[kBufferSize - 1] = '\0';
115 bool status = converter.ToExponential(d, fraction_digits, &builder);
116 ASSERT(status);
117 return String::New(builder.Finalize());
118}
119
120StringPtr DoubleToStringAsPrecision(double d, int precision) {
121 const int kMinPrecisionDigits = 1;
122 const int kMaxPrecisionDigits = 21;
123 const int kMaxLeadingPaddingZeroes = 6;
124 const int kMaxTrailingPaddingZeroes = 0;
125 const int kConversionFlags =
127 const int kBufferSize = 128;
128
129 USE(kMinPrecisionDigits);
130 USE(kMaxPrecisionDigits);
131 // The output contains the sign, a potential leading 0, the decimal point,
132 // at most kMax{Leading|Trailing} padding zeroes, precision digits,
133 // the exponent-character, the exponent-sign, three exponent digits
134 // plus the \0.
135 // Note that padding and exponent are exclusive. We still add them up.
136 ASSERT(kBufferSize >= 1 + 1 + 1 + kMaxLeadingPaddingZeroes +
137 kMaxTrailingPaddingZeroes + kMaxPrecisionDigits +
138 1 + 1 + 3 + 1);
139
140 ASSERT(kMinPrecisionDigits <= precision && precision <= kMaxPrecisionDigits);
141
143 kConversionFlags, kInfinitySymbol, kNaNSymbol, kExponentChar, 0,
144 0, // Ignored in precision mode.
145 kMaxLeadingPaddingZeroes, kMaxTrailingPaddingZeroes);
146
147 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize);
148 buffer[kBufferSize - 1] = '\0';
150 bool status = converter.ToPrecision(d, precision, &builder);
151 ASSERT(status);
152 return String::New(builder.Finalize());
153}
154
155bool CStringToDouble(const char* str, intptr_t length, double* result) {
156 if (length == 0) {
157 return false;
158 }
159
163
164 int parsed_count = 0;
165 *result =
166 converter.StringToDouble(str, static_cast<int>(length), &parsed_count);
167 return (parsed_count == length);
168}
169
170IntegerPtr DoubleToInteger(Zone* zone, double val) {
171 if (isinf(val) || isnan(val)) {
172 const Array& args = Array::Handle(zone, Array::New(1));
173 args.SetAt(0, String::Handle(zone, String::New("Infinity or NaN toInt")));
175 }
176 int64_t ival = 0;
177 if (val <= static_cast<double>(kMinInt64)) {
178 ival = kMinInt64;
179 } else if (val >= static_cast<double>(kMaxInt64)) {
180 ival = kMaxInt64;
181 } else { // Representable in int64_t.
182 ival = static_cast<int64_t>(val);
183 }
184 return Integer::New(ival);
185}
186
187} // namespace dart
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static const size_t kBufferSize
Definition SkString.cpp:27
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
static DART_NORETURN void ThrowByType(ExceptionType type, const Array &arguments)
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition object.cc:23063
static Object & Handle()
Definition object.h:407
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition object.cc:23777
Zone * zone() const
static Thread * Current()
Definition thread.h:361
ElementType * Alloc(intptr_t length)
#define ASSERT(E)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
GAsyncResult * result
size_t length
constexpr int64_t kMaxInt64
Definition globals.h:486
constexpr int64_t kMinInt64
Definition globals.h:485
StringPtr DoubleToStringAsPrecision(double d, int precision)
void DoubleToCString(double d, char *buffer, int buffer_size)
bool CStringToDouble(const char *str, intptr_t length, double *result)
IntegerPtr DoubleToInteger(Zone *zone, double val)
StringPtr DoubleToStringAsFixed(double d, int fraction_digits)
StringPtr DoubleToStringAsExponential(double d, int fraction_digits)
static constexpr const char * kInfinitySymbol
static void USE(T &&)
Definition globals.h:618
static constexpr const char * kNaNSymbol
static constexpr char kExponentChar