Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
fmt
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
fmt
Commits
7395472d
Commit
7395472d
authored
Nov 22, 2019
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor floating-point formatting
parent
9108b25d
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
26 additions
and
32 deletions
+26
-32
include/fmt/format-inl.h
include/fmt/format-inl.h
+6
-6
include/fmt/format.h
include/fmt/format.h
+17
-24
src/format.cc
src/format.cc
+2
-1
test/format-impl-test.cc
test/format-impl-test.cc
+1
-1
No files found.
include/fmt/format-inl.h
View file @
7395472d
...
...
@@ -1029,12 +1029,12 @@ void fallback_format(Double d, buffer<char>& buf, int& exp10) {
}
}
template
<
typename
Double
,
enable_if_t
<
(
sizeof
(
Double
)
==
sizeof
(
uint64_t
)),
int
>
>
bool
grisu_format
(
Double
value
,
buffer
<
char
>&
buf
,
int
precision
,
unsigned
options
,
int
&
exp
)
{
template
<
typename
Float
,
enable_if_t
<
(
sizeof
(
Float
)
==
sizeof
(
uint64_t
)),
int
>
>
bool
grisu_format
(
Float
value
,
int
precision
,
buffer
<
char
>&
buf
,
float_spec
spec
,
int
&
exp
)
{
FMT_ASSERT
(
value
>=
0
,
"value is negative"
);
const
bool
fixed
=
(
options
&
grisu_options
::
fixed
)
!=
0
;
const
bool
fixed
=
spec
.
format
==
float_format
::
fixed
;
if
(
value
<=
0
)
{
// <= instead of == to silence a warning.
if
(
precision
<=
0
||
!
fixed
)
{
exp
=
0
;
...
...
@@ -1071,7 +1071,7 @@ bool grisu_format(Double value, buffer<char>& buf, int precision,
}
else
{
fp
fp_value
;
fp
lower
,
upper
;
// w^- and w^+ in the Grisu paper.
if
(
(
options
&
grisu_options
::
binary32
)
!=
0
)
if
(
spec
.
binary32
)
fp_value
.
assign_float_with_boundaries
(
value
,
lower
,
upper
);
else
fp_value
.
assign_with_boundaries
(
value
,
lower
,
upper
);
...
...
include/fmt/format.h
View file @
7395472d
...
...
@@ -1075,6 +1075,7 @@ struct float_spec {
bool
locale
;
bool
percent
;
bool
alt
;
bool
binary32
;
};
struct
gen_digits_params
{
...
...
@@ -1116,7 +1117,7 @@ template <typename Char> class float_writer {
gen_digits_params
params_
;
Char
decimal_point_
;
template
<
typename
It
>
It
grisu_
prettify
(
It
it
)
const
{
template
<
typename
It
>
It
prettify
(
It
it
)
const
{
// pow(10, full_exp - 1) <= v <= pow(10, full_exp).
int
full_exp
=
num_digits_
+
exp_
;
if
(
params_
.
format
==
float_format
::
exp
)
{
...
...
@@ -1194,7 +1195,7 @@ template <typename Char> class float_writer {
?
float_format
::
fixed
:
float_format
::
exp
;
}
size_
=
grisu_
prettify
(
counting_iterator
()).
count
();
size_
=
prettify
(
counting_iterator
()).
count
();
size_
+=
params_
.
sign
?
1
:
0
;
}
...
...
@@ -1203,20 +1204,16 @@ template <typename Char> class float_writer {
template
<
typename
It
>
void
operator
()(
It
&&
it
)
{
if
(
params_
.
sign
)
*
it
++
=
static_cast
<
Char
>
(
data
::
signs
[
params_
.
sign
]);
it
=
grisu_
prettify
(
it
);
it
=
prettify
(
it
);
}
};
namespace
grisu_options
{
enum
{
fixed
=
1
,
binary32
=
2
};
}
// Formats value using the Grisu algorithm:
// https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
template
<
typename
Double
,
FMT_ENABLE_IF
(
sizeof
(
Double
)
==
sizeof
(
uint64_t
))>
FMT_API
bool
grisu_format
(
Double
,
buffer
<
char
>&
,
int
,
unsigned
,
int
&
);
template
<
typename
Double
,
FMT_ENABLE_IF
(
sizeof
(
Double
)
!=
sizeof
(
uint64_t
))>
inline
bool
grisu_format
(
Double
,
buffer
<
char
>&
,
int
,
unsigned
,
int
&
)
{
template
<
typename
Float
,
FMT_ENABLE_IF
(
sizeof
(
Float
)
==
sizeof
(
uint64_t
))>
FMT_API
bool
grisu_format
(
Float
,
int
,
buffer
<
char
>&
,
float_spec
,
int
&
);
template
<
typename
Float
,
FMT_ENABLE_IF
(
sizeof
(
Float
)
!=
sizeof
(
uint64_t
))>
inline
bool
grisu_format
(
Float
,
int
,
buffer
<
char
>&
,
float_spec
,
int
&
)
{
return
false
;
}
...
...
@@ -1739,17 +1736,13 @@ template <typename Range> class basic_writer {
return
;
}
int
precision
=
specs
.
precision
>=
0
||
!
specs
.
type
?
specs
.
precision
:
6
;
int
num_digits
=
fspec
.
format
==
float_format
::
exp
?
precision
+
1
:
precision
;
unsigned
options
=
0
;
if
(
fspec
.
format
==
float_format
::
fixed
)
options
|=
grisu_options
::
fixed
;
if
(
const_check
(
std
::
is_same
<
T
,
float
>
()))
options
|=
grisu_options
::
binary32
;
if
(
fspec
.
format
==
float_format
::
exp
)
++
precision
;
if
(
const_check
(
std
::
is_same
<
T
,
float
>
()))
fspec
.
binary32
=
true
;
if
(
const_check
(
FMT_DEPRECATED_PERCENT
)
&&
fspec
.
percent
)
value
*=
100
;
int
exp
=
0
;
bool
use_grisu
=
internal
::
use_grisu
<
T
>
()
&&
grisu_format
(
static_cast
<
double
>
(
value
),
buffer
,
num_digits
,
options
,
exp
);
bool
use_grisu
=
internal
::
use_grisu
<
T
>
()
&&
grisu_format
(
static_cast
<
double
>
(
value
),
precision
,
buffer
,
fspec
,
exp
);
if
(
!
use_grisu
)
exp
=
sprintf_format
(
value
,
precision
,
fspec
,
buffer
);
if
(
const_check
(
FMT_DEPRECATED_PERCENT
)
&&
fspec
.
percent
)
{
...
...
@@ -1759,18 +1752,18 @@ template <typename Range> class basic_writer {
auto
params
=
gen_digits_params
();
params
.
sign
=
sign
;
params
.
format
=
fspec
.
format
;
params
.
num_digits
=
num_digits
;
params
.
num_digits
=
precision
;
params
.
trailing_zeros
=
(
precision
!=
0
&&
(
!
specs
.
type
||
fspec
.
format
==
float_format
::
fixed
||
fspec
.
format
==
float_format
::
exp
))
||
specs
.
alt
;
params
.
upper
=
fspec
.
upper
;
num_digits
=
static_cast
<
int
>
(
buffer
.
size
());
char_type
point
=
fspec
.
locale
?
decimal_point
<
char_type
>
(
locale_
)
:
static_cast
<
char_type
>
(
'.'
);
write_padded
(
specs
,
float_writer
<
char_type
>
(
buffer
.
data
(),
num_digits
,
exp
,
params
,
point
));
write_padded
(
specs
,
float_writer
<
char_type
>
(
buffer
.
data
(),
static_cast
<
int
>
(
buffer
.
size
()),
exp
,
params
,
point
));
}
void
write
(
char
value
)
{
...
...
src/format.cc
View file @
7395472d
...
...
@@ -11,7 +11,8 @@ FMT_BEGIN_NAMESPACE
template
struct
FMT_API
internal
::
basic_data
<
void
>;
// Workaround a bug in MSVC2013 that prevents instantiation of grisu_format.
bool
(
*
instantiate_grisu_format
)(
double
,
internal
::
buffer
<
char
>&
,
int
,
unsigned
,
bool
(
*
instantiate_grisu_format
)(
double
,
int
,
internal
::
buffer
<
char
>&
,
internal
::
float_spec
,
int
&
)
=
internal
::
grisu_format
;
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
...
...
test/format-impl-test.cc
View file @
7395472d
...
...
@@ -327,7 +327,7 @@ TEST(FPTest, FixedHandler) {
TEST
(
FPTest
,
GrisuFormatCompilesWithNonIEEEDouble
)
{
fmt
::
memory_buffer
buf
;
int
exp
=
0
;
grisu_format
(
4.2
f
,
buf
,
-
1
,
false
,
exp
);
grisu_format
(
4.2
f
,
-
1
,
buf
,
fmt
::
internal
::
float_spec
()
,
exp
);
}
template
<
typename
T
>
struct
value_extractor
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment