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

Side by Side Diff: runtime/lib/double.cc

Issue 2005723004: Fraction class prototype and test (not to be committed). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: work in progress Created 4 years, 5 months 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
« no previous file with comments | « runtime/lib/core_sources.gypi ('k') | runtime/lib/double.dart » ('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 (c) 2011, the Dart project authors. Please see the AUTHORS 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/bootstrap_natives.h" 5 #include "vm/bootstrap_natives.h"
6 6
7 #include "platform/math.h" 7 #include "platform/math.h"
8 8
9 #include "vm/code_generator.h" // DartModulo. 9 #include "vm/code_generator.h" // DartModulo.
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 11 matching lines...) Expand all
22 DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 2) { 22 DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 2) {
23 ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull()); 23 ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull());
24 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(1)); 24 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(1));
25 if (FLAG_trace_intrinsified_natives) { 25 if (FLAG_trace_intrinsified_natives) {
26 OS::Print("Double_doubleFromInteger %s\n", value.ToCString()); 26 OS::Print("Double_doubleFromInteger %s\n", value.ToCString());
27 } 27 }
28 return Double::New(value.AsDoubleValue()); 28 return Double::New(value.AsDoubleValue());
29 } 29 }
30 30
31 31
32 DEFINE_NATIVE_ENTRY(Double_doubleFromFraction, 2) {
33 const Integer& numerator = Integer::CheckedHandle(arguments->NativeArgAt(0));
34 const Integer& denominator =
35 Integer::CheckedHandle(arguments->NativeArgAt(1));
36 return Double::New(numerator.AsDoubleValue() / denominator.AsDoubleValue());
37 }
38
39
32 DEFINE_NATIVE_ENTRY(Double_add, 2) { 40 DEFINE_NATIVE_ENTRY(Double_add, 2) {
33 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); 41 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value();
34 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); 42 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
35 double right = right_object.value(); 43 double right = right_object.value();
36 if (FLAG_trace_intrinsified_natives) { 44 if (FLAG_trace_intrinsified_natives) {
37 OS::Print("Double_add %f + %f\n", left, right); 45 OS::Print("Double_add %f + %f\n", left, right);
38 } 46 }
39 return Double::New(left + right); 47 return Double::New(left + right);
40 } 48 }
41 49
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 if (exponent == 0) { 112 if (exponent == 0) {
105 // The double fits in a Smi or Mint. 113 // The double fits in a Smi or Mint.
106 return Integer::New(ival); 114 return Integer::New(ival);
107 } 115 }
108 Integer& result = Integer::Handle(); 116 Integer& result = Integer::Handle();
109 result = Bigint::NewFromShiftedInt64(ival, exponent); 117 result = Bigint::NewFromShiftedInt64(ival, exponent);
110 return result.AsValidInteger(); 118 return result.AsValidInteger();
111 } 119 }
112 120
113 121
122 static void DoubleToFraction(
123 double val, const Array& fract, const char* error_msg) {
124 if (isinf(val) || isnan(val)) {
125 const Array& args = Array::Handle(Array::New(1));
126 args.SetAt(0, String::Handle(String::New(error_msg)));
127 Exceptions::ThrowByType(Exceptions::kUnsupported, args);
128 }
129 // TODO(regis): Convert inf and nan to fraction.
130 // Now that we have a C++ Fraction class, this call should return the
131 // fraction instance, rather than set the array elements.
132 DoubleInternals internals = DoubleInternals(val);
133 ASSERT(!internals.IsSpecial()); // Only Infinity and NaN are special.
134 uint64_t significand = internals.Significand();
135 intptr_t exponent = internals.Exponent();
136 Integer& denominator = Integer::Handle();
137 if (exponent < 0) {
138 if (exponent > -63) {
139 // The denominator fits in a Smi or Mint.
140 denominator = Integer::New(1LL << -exponent);
141 } else {
142 denominator = Bigint::NewFromShiftedInt64(1, -exponent);
143 }
144 exponent = 0;
145 } else {
146 denominator = Integer::New(1);
147 if (exponent <= 10) {
148 // A double significand has at most 53 bits. The following shift will
149 // hence not overflow, and yield an integer of at most 63 bits.
150 significand <<= exponent;
151 exponent = 0;
152 }
153 }
154 // A significand has at most 63 bits (after the shift above).
155 // The cast to int64_t is hence safe.
156 int64_t ival = static_cast<int64_t>(significand);
157 if (internals.Sign() < 0) {
158 ival = -ival;
159 }
160 Integer& numerator = Integer::Handle();
161 if (exponent == 0) {
162 // The numerator fits in a Smi or Mint.
163 numerator = Integer::New(ival);
164 } else {
165 numerator = Bigint::NewFromShiftedInt64(ival, exponent);
166 numerator = numerator.AsValidInteger(); // May fit in a Smi or Mint.
167 }
168 fract.SetAt(0, numerator);
169 fract.SetAt(1, denominator);
170 }
171
172
114 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) { 173 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) {
115 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); 174 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value();
116 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); 175 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
117 double right = right_object.value(); 176 double right = right_object.value();
118 if (FLAG_trace_intrinsified_natives) { 177 if (FLAG_trace_intrinsified_natives) {
119 OS::Print("Double_trunc_div %f ~/ %f\n", left, right); 178 OS::Print("Double_trunc_div %f ~/ %f\n", left, right);
120 } 179 }
121 return DoubleToInteger(trunc(left / right), 180 return DoubleToInteger(trunc(left / right),
122 "Result of truncating division is Infinity or NaN"); 181 "Result of truncating division is Infinity or NaN");
123 } 182 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 // MAC OSX math library produces old style cast warning. 262 // MAC OSX math library produces old style cast warning.
204 #pragma GCC diagnostic ignored "-Wold-style-cast" 263 #pragma GCC diagnostic ignored "-Wold-style-cast"
205 #endif 264 #endif
206 265
207 DEFINE_NATIVE_ENTRY(Double_toInt, 1) { 266 DEFINE_NATIVE_ENTRY(Double_toInt, 1) {
208 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); 267 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
209 return DoubleToInteger(arg.value(), "Infinity or NaN toInt"); 268 return DoubleToInteger(arg.value(), "Infinity or NaN toInt");
210 } 269 }
211 270
212 271
272 DEFINE_NATIVE_ENTRY(Double_toFraction, 2) {
273 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
274 const Array& fract = Array::CheckedHandle(arguments->NativeArgAt(1));
275 ASSERT(fract.Length() == 2);
276 DoubleToFraction(arg.value(), fract, "Infinity or NaN toFraction");
277 return Object::null(); // Result in fract[0] and fract[1].
278 }
279
280
213 DEFINE_NATIVE_ENTRY(Double_parse, 3) { 281 DEFINE_NATIVE_ENTRY(Double_parse, 3) {
214 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); 282 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
215 GET_NON_NULL_NATIVE_ARGUMENT(Integer, startValue, arguments->NativeArgAt(1)); 283 GET_NON_NULL_NATIVE_ARGUMENT(Integer, startValue, arguments->NativeArgAt(1));
216 GET_NON_NULL_NATIVE_ARGUMENT(Integer, endValue, arguments->NativeArgAt(2)); 284 GET_NON_NULL_NATIVE_ARGUMENT(Integer, endValue, arguments->NativeArgAt(2));
217 285
218 const intptr_t start = startValue.AsTruncatedUint32Value(); 286 const intptr_t start = startValue.AsTruncatedUint32Value();
219 const intptr_t end = endValue.AsTruncatedUint32Value(); 287 const intptr_t end = endValue.AsTruncatedUint32Value();
220 const intptr_t len = value.Length(); 288 const intptr_t len = value.Length();
221 289
222 // Indices should be inside the string, and 0 <= start < end <= len. 290 // Indices should be inside the string, and 0 <= start < end <= len.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 DEFINE_NATIVE_ENTRY(Double_flipSignBit, 1) { 378 DEFINE_NATIVE_ENTRY(Double_flipSignBit, 1) {
311 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); 379 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
312 const double in_val = arg.value(); 380 const double in_val = arg.value();
313 const int64_t bits = bit_cast<int64_t, double>(in_val) ^ kSignBitDouble; 381 const int64_t bits = bit_cast<int64_t, double>(in_val) ^ kSignBitDouble;
314 return Double::New(bit_cast<double, int64_t>(bits)); 382 return Double::New(bit_cast<double, int64_t>(bits));
315 } 383 }
316 384
317 // Add here only functions using/referring to old-style casts. 385 // Add here only functions using/referring to old-style casts.
318 386
319 } // namespace dart 387 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/core_sources.gypi ('k') | runtime/lib/double.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698