|
13 | 13 |
|
14 | 14 | #include <assert.h>
|
15 | 15 |
|
| 16 | +// Note: using C++ stdio just to get a locale-independent |
| 17 | +// way to format floating-point values. |
| 18 | +// |
| 19 | +// TODO: Go ahead and implement teh Dragon4 algorithm so |
| 20 | +// that we can print floating-point values to arbitrary |
| 21 | +// precision as needed. |
| 22 | +#include <sstream> |
| 23 | + |
16 | 24 | #ifdef _WIN32
|
17 | 25 | #include <d3dcompiler.h>
|
18 | 26 | #pragma warning(disable:4996)
|
@@ -546,10 +554,34 @@ struct EmitVisitor
|
546 | 554 |
|
547 | 555 | void Emit(double value)
|
548 | 556 | {
|
549 |
| - // TODO(tfoley): need to print things in a way that can round-trip |
550 |
| - char buffer[128]; |
551 |
| - sprintf(buffer, "%.20ff", value); |
552 |
| - Emit(buffer); |
| 557 | + // There are a few different requirements here that we need to deal with: |
| 558 | + // |
| 559 | + // 1) We need to print somethign that is valid syntax in the target language |
| 560 | + // (this means that hex floats are off the table for now) |
| 561 | + // |
| 562 | + // 2) We need our printing to be independent of the current global locale in C, |
| 563 | + // so that we don't depend on the application leaving it as the default, |
| 564 | + // and we also don't revert any changes they make. |
| 565 | + // (this means that `sprintf` and friends are off the table) |
| 566 | + // |
| 567 | + // 3) We need to be sure that floating-point literals specified by the user will |
| 568 | + // "round-trip" and turn into the same value when parsed back in. This means |
| 569 | + // that we need to print a reasonable number of digits of precision. |
| 570 | + // |
| 571 | + // For right now, the easiest option that can balance these is to use |
| 572 | + // the C++ standard library `iostream`s, because they support an explicit locale, |
| 573 | + // and can (hopefully) print floating-point numbers accurately. |
| 574 | + // |
| 575 | + // Eventually, the right move here would be to implement proper floating-point |
| 576 | + // number formatting ourselves, but that would require extensive testing to |
| 577 | + // make sure we get it right. |
| 578 | + |
| 579 | + std::ostringstream stream; |
| 580 | + stream.imbue(std::locale::classic()); |
| 581 | + stream.precision(20); |
| 582 | + stream << value; |
| 583 | + |
| 584 | + Emit(stream.str().c_str()); |
553 | 585 | }
|
554 | 586 |
|
555 | 587 |
|
|
0 commit comments