|
1 | | -# Format a floating-point number as a string with a specific precision. Similar to |
2 | | -# `@sprintf("%.$(dp)f", val)`. |
3 | | - |
4 | | -if VERSION < v"0.6-" |
5 | | - function float_string(val::AbstractFloat, dp::Integer) |
6 | | - # On Julia 0.5 positive 0.0 can have extra bits. No other integer floating-point |
7 | | - # seems to have this problem. |
8 | | - isequal(val, 0.0) && return rpad("0.", dp, '0') |
9 | | - format = "%.$(dp)f" |
10 | | - @eval @sprintf($("%.$(dp)f"), nextfloat(0.0)) |
11 | | - @eval begin |
12 | | - let buffer = Array{UInt8}(100 + $dp) |
13 | | - ccall((:snprintf, :libc), Int, (Ptr{UInt8}, Csize_t, Cstring, Cdouble), buffer, length(buffer), $format, $val) |
14 | | - unsafe_string(pointer(buffer)) |
15 | | - end |
16 | | - end |
17 | | - end |
18 | | -else |
19 | | - function float_string(val::AbstractFloat, dp::Integer) |
20 | | - buffer = Array{UInt8}(100 + dp) |
21 | | - ccall((:snprintf, :libc), Int, (Ptr{UInt8}, Csize_t, Cstring, Cdouble), buffer, length(buffer), "%.$(dp)f", val) |
22 | | - unsafe_string(pointer(buffer)) |
| 1 | +# Print the floating-point number with precision high enough that rounding never occurs |
| 2 | +function float_string(val::AbstractFloat) |
| 3 | + # Note: This function could simply be `@sprintf("%.325f", val)` once the following |
| 4 | + # issue is solved: https://github.com/JuliaLang/julia/issues/22137 |
| 5 | + dp = 325 # Number of decimal places to print `nextfloat(0.0)` without rounding |
| 6 | + int = trunc(BigInt, val) |
| 7 | + if abs(int) > 0 |
| 8 | + dp -= ndigits(int) |
23 | 9 | end |
| 10 | + @eval @sprintf($("%.$(dp)f"), $val) |
24 | 11 | end |
25 | 12 |
|
26 | 13 | # FixedDecimal methods which perform an alternative method of trunc, floor, and ceil which |
|
30 | 17 | function integer_alt{T<:Integer}(::Type{T}, dp::Integer, val::AbstractFloat) |
31 | 18 | # Note: Use a precision larger than the value can represent so that `sprintf` doesn't |
32 | 19 | # perform any rounding. |
33 | | - # TODO: Ideally we could be using just be using `@sprintf("%.325f", val)` once this |
34 | | - # issue is fixed: https://github.com/JuliaLang/julia/issues/22137 |
35 | | - str = float_string(val, 325) # 325 digits is large enough for `nextfloat(0.0)` |
| 20 | + str = float_string(val) |
36 | 21 | sign = T(first(str) == '-' ? -1 : 1) |
37 | 22 | decimal = findfirst(str, '.') |
38 | 23 | int_start = sign < 0 ? 2 : 1 |
|
0 commit comments