File: dtoa.cpp

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (147 lines) | stat: -rw-r--r-- 6,056 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/****************************************************************
 *
 * The author of this software is David M. Gay.
 *
 * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
 * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2010, 2012 Apple Inc.
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose without fee is hereby granted, provided that this entire notice
 * is included in all copies of any software which is or includes a copy
 * or modification of this software and in all copies of the supporting
 * documentation for such software.
 *
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
 *
 ***************************************************************/

/* Please send bug reports to David M. Gay (dmg at acm dot org,
 * with " at " changed at "@" and " dot " changed to ".").    */

/* On a machine with IEEE extended-precision registers, it is
 * necessary to specify double-precision (53-bit) rounding precision
 * before invoking strtod or dtoa.  If the machine uses (the equivalent
 * of) Intel 80x87 arithmetic, the call
 *    _control87(PC_53, MCW_PC);
 * does this with many compilers.  Whether this or another call is
 * appropriate depends on the compiler; for this to work, it may be
 * necessary to #include "float.h" or another system-dependent header
 * file.
 */

#include "wtf/dtoa.h"

#include "wtf/Vector.h"
#include <string.h>

namespace WTF {

const char* numberToString(double d, NumberToStringBuffer buffer) {
  double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
  const double_conversion::DoubleToStringConverter& converter =
      double_conversion::DoubleToStringConverter::EcmaScriptConverter();
  converter.ToShortest(d, &builder);
  return builder.Finalize();
}

static inline const char* formatStringTruncatingTrailingZerosIfNeeded(
    NumberToStringBuffer buffer,
    double_conversion::StringBuilder& builder) {
  size_t length = builder.position();

  // If there is an exponent, stripping trailing zeros would be incorrect.
  // FIXME: Zeros should be stripped before the 'e'.
  if (memchr(buffer, 'e', length))
    return builder.Finalize();

  size_t decimalPointPosition = 0;
  for (; decimalPointPosition < length; ++decimalPointPosition) {
    if (buffer[decimalPointPosition] == '.')
      break;
  }

  // No decimal seperator found, early exit.
  if (decimalPointPosition == length)
    return builder.Finalize();

  size_t truncatedLength = length - 1;
  for (; truncatedLength > decimalPointPosition; --truncatedLength) {
    if (buffer[truncatedLength] != '0')
      break;
  }

  // No trailing zeros found to strip.
  if (truncatedLength == length - 1)
    return builder.Finalize();

  // If we removed all trailing zeros, remove the decimal point as well.
  if (truncatedLength == decimalPointPosition) {
    DCHECK_GT(truncatedLength, 0u);
    --truncatedLength;
  }

  // Truncate the StringBuilder, and return the final result.
  builder.SetPosition(truncatedLength + 1);
  return builder.Finalize();
}

const char* numberToFixedPrecisionString(double d,
                                         unsigned significantFigures,
                                         NumberToStringBuffer buffer) {
  // Mimic String::format("%.[precision]g", ...), but use dtoas rounding
  // facilities.
  // "g": Signed value printed in f or e format, whichever is more compact for
  // the given value and precision.
  // The e format is used only when the exponent of the value is less than -4 or
  // greater than or equal to the precision argument. Trailing zeros are
  // truncated, and the decimal point appears only if one or more digits follow
  // it.
  // "precision": The precision specifies the maximum number of significant
  // digits printed.
  double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
  const double_conversion::DoubleToStringConverter& converter =
      double_conversion::DoubleToStringConverter::EcmaScriptConverter();
  converter.ToPrecision(d, significantFigures, &builder);
  // FIXME: Trailing zeros should never be added in the first place. The
  // current implementation does not strip when there is an exponent, eg.
  // 1.50000e+10.
  return formatStringTruncatingTrailingZerosIfNeeded(buffer, builder);
}

const char* numberToFixedWidthString(double d,
                                     unsigned decimalPlaces,
                                     NumberToStringBuffer buffer) {
  // Mimic String::format("%.[precision]f", ...), but use dtoas rounding
  // facilities.
  // "f": Signed value having the form [ - ]dddd.dddd, where dddd is one or more
  // decimal digits.  The number of digits before the decimal point depends on
  // the magnitude of the number, and the number of digits after the decimal
  // point depends on the requested precision.
  // "precision": The precision value specifies the number of digits after the
  // decimal point.  If a decimal point appears, at least one digit appears
  // before it.  The value is rounded to the appropriate number of digits.
  double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
  const double_conversion::DoubleToStringConverter& converter =
      double_conversion::DoubleToStringConverter::EcmaScriptConverter();
  converter.ToFixed(d, decimalPlaces, &builder);
  return builder.Finalize();
}

namespace Internal {

double parseDoubleFromLongString(const UChar* string,
                                 size_t length,
                                 size_t& parsedLength) {
  Vector<LChar> conversionBuffer(length);
  for (size_t i = 0; i < length; ++i)
    conversionBuffer[i] = isASCII(string[i]) ? string[i] : 0;
  return parseDouble(conversionBuffer.data(), length, parsedLength);
}

}  // namespace Internal

}  // namespace WTF