|
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