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

Unified Diff: src/grisu3.cc

Issue 866002: Fast double-to-ascii conversion. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/grisu3.h ('k') | src/powers_ten.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/grisu3.cc
===================================================================
--- src/grisu3.cc (revision 4092)
+++ src/grisu3.cc (working copy)
@@ -74,8 +74,10 @@
template<int alpha, int gamma>
-bool Grisu3<alpha, gamma>::grisu3(
- double v, char* buffer, int* length, int* decimal_exponent) {
+bool Grisu3<alpha, gamma>::grisu3(double v,
+ char* buffer,
+ int* length,
+ int* decimal_exponent) {
DiyFp w = Double(v).AsNormalizedDiyFp();
// boundary_minus and boundary_plus are the boundaries between v and its
// neighbors. Any number strictly between boundary_minus and boundary_plus
@@ -147,8 +149,12 @@
// numbers. If the precision is not enough to guarantee all the postconditions
// then false is returned. This usually happens rarely (~0.5%).
template<int alpha, int gamma>
-bool Grisu3<alpha, gamma>::DigitGen(
- DiyFp low, DiyFp w, DiyFp high, char* buffer, int* len, int* kappa) {
+bool Grisu3<alpha, gamma>::DigitGen(DiyFp low,
+ DiyFp w,
+ DiyFp high,
+ char* buffer,
+ int* len,
+ int* kappa) {
ASSERT(low.e() == w.e() && w.e() == high.e());
ASSERT(low.f() + 1 <= high.f() - 1);
ASSERT(alpha <= w.e() && w.e() <= gamma);
@@ -177,8 +183,10 @@
// furthermore receive the maximum number of bits 'number' has.
// If number_bits == 0 then 0^-1 is returned
// The number of bits must be <= 32.
-static void BiggestPowerTen(uint32_t number, int number_bits,
- uint32_t* power, int* exponent) {
+static void BiggestPowerTen(uint32_t number,
+ int number_bits,
+ uint32_t* power,
+ int* exponent) {
switch (number_bits) {
case 32:
case 31:
@@ -294,8 +302,12 @@
// represents w. However we have to pay attention to low, high and w's
// imprecision.
template<int alpha, int gamma>
-bool Grisu3<alpha, gamma>::DigitGen_m60_m32(
- DiyFp low, DiyFp w, DiyFp high, char* buffer, int* length, int* kappa) {
+bool Grisu3<alpha, gamma>::DigitGen_m60_m32(DiyFp low,
+ DiyFp w,
+ DiyFp high,
+ char* buffer,
+ int* length,
+ int* kappa) {
// low, w and high are imprecise, but by less than one ulp (unit in the last
// place).
// If we remove (resp. add) 1 ulp from low (resp. high) we are certain that
@@ -321,8 +333,10 @@
// We use too_high for the digit_generation and stop as soon as possible.
// If we stop early we effectively round down.
DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
- uint32_t integrals = too_high.f() >> -one.e(); // Division by one.
- uint64_t fractionals = too_high.f() & (one.f() - 1); // Modulo by one.
+ // Division by one is a shift.
+ uint32_t integrals = static_cast<uint32_t>(too_high.f() >> -one.e());
+ // Modulo by one is an and.
+ uint64_t fractionals = too_high.f() & (one.f() - 1);
uint32_t divider;
int divider_exponent;
BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
@@ -332,7 +346,7 @@
// Loop invariant: buffer = too_high / 10^kappa (integer division)
// The invariant holds for the first iteration: kappa has been initialized
// with the divider exponent + 1. And the divider is the biggest power of ten
- // that fits into the bits that had been reserved for the integrals.
+ // that is smaller than integrals.
while (*kappa > 0) {
int digit = integrals / divider;
buffer[*length] = '0' + digit;
@@ -376,7 +390,8 @@
unsafe_interval.set_e(unsafe_interval.e() + 1); // Will be optimized out.
one.set_f(one.f() >> 1);
one.set_e(one.e() + 1);
- int digit = fractionals >> -one.e(); // Integer division by one.
+ // Integer division by one.
+ int digit = static_cast<int>(fractionals >> -one.e());
buffer[*length] = '0' + digit;
(*length)++;
fractionals &= one.f() - 1; // Modulo by one.
@@ -402,10 +417,13 @@
// Output: returns true on success.
// Modifies the generated digits in the buffer to approach (round towards) w.
template<int alpha, int gamma>
-bool Grisu3<alpha, gamma>::RoundWeed(
- char* buffer, int length, uint64_t distance_too_high_w,
- uint64_t unsafe_interval, uint64_t rest, uint64_t ten_kappa,
- uint64_t unit) {
+bool Grisu3<alpha, gamma>::RoundWeed(char* buffer,
+ int length,
+ uint64_t distance_too_high_w,
+ uint64_t unsafe_interval,
+ uint64_t rest,
+ uint64_t ten_kappa,
+ uint64_t unit) {
uint64_t small_distance = distance_too_high_w - unit;
uint64_t big_distance = distance_too_high_w + unit;
// Let w- = too_high - big_distance, and
@@ -456,8 +474,7 @@
}
-bool grisu3(double v,
- char* buffer, int* sign, int* length, int* decimal_point) {
+bool grisu3(double v, char* buffer, int* sign, int* length, int* point) {
ASSERT(v != 0);
ASSERT(!Double(v).IsSpecial());
@@ -469,7 +486,7 @@
}
int decimal_exponent;
bool result = Grisu3<-60, -32>::grisu3(v, buffer, length, &decimal_exponent);
- *decimal_point = *length + decimal_exponent;
+ *point = *length + decimal_exponent;
buffer[*length] = '\0';
return result;
}
« no previous file with comments | « src/grisu3.h ('k') | src/powers_ten.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698