@@ -894,28 +894,63 @@ end
894
894
895
895
setprecision (f:: Function , precision:: Integer ) = setprecision (f, BigFloat, precision)
896
896
897
- function string (x:: BigFloat )
898
- isfinite (x) || return string (Float64 (x))
899
-
900
- # In general, the number of decimal places needed to read back the number exactly
901
- # is, excluding the most significant, ceil(log(10, 2^precision(x)))
902
- k = ceil (Int32, precision (x) * 0.3010299956639812 )
903
- lng = k + Int32 (8 ) # Add space for the sign, the most significand digit, the dot and the exponent
904
- buf = Base. StringVector (lng + 1 )
905
- # format strings are guaranteed to contain no NUL, so we don't use Cstring
906
- lng = ccall ((:mpfr_snprintf ,:libmpfr ), Int32, (Ptr{UInt8}, Culong, Ptr{UInt8}, Ref{BigFloat}. .. ), buf, lng + 1 , " %.Re" , x)
907
- if lng < k + 5 # print at least k decimal places
908
- lng = ccall ((:mpfr_sprintf ,:libmpfr ), Int32, (Ptr{UInt8}, Ptr{UInt8}, Ref{BigFloat}. .. ), buf, " %.$(k) Re" , x)
909
- elseif lng > k + 8
910
- buf = Base. StringVector (lng + 1 )
911
- lng = ccall ((:mpfr_snprintf ,:libmpfr ), Int32, (Ptr{UInt8}, Culong, Ptr{UInt8}, Ref{BigFloat}. .. ), buf, lng + 1 , " %.Re" , x)
897
+ function string_mpfr (x:: BigFloat , fmt:: String )
898
+ buf = Base. StringVector (0 )
899
+ s = _calculate_buffer_size! (buf, fmt, x)
900
+ resize! (buf, s)
901
+ _fill_buffer! (buf, fmt, x)
902
+ String (buf)
903
+ end
904
+
905
+ function _calculate_buffer_size! (buf, fmt, x:: BigFloat )
906
+ ccall ((:mpfr_snprintf ,:libmpfr ),
907
+ Int32, (Ptr{UInt8}, Culong, Ptr{UInt8}, Ptr{BigFloat}. .. ),
908
+ buf, 0 , fmt, & x)
909
+ end
910
+
911
+ function _fill_buffer! (buf, fmt, x:: BigFloat )
912
+ s = length (buf)
913
+ # we temporarily need one more item in buffer to capture null termination
914
+ resize! (buf, s + 1 )
915
+ n = ccall ((:mpfr_sprintf ,:libmpfr ), Int32, (Ptr{UInt8}, Ptr{UInt8}, Ptr{BigFloat}. .. ), buf, fmt, & x)
916
+ @assert n + 1 == length (buf)
917
+ @assert last (buf) == 0x00
918
+ resize! (buf, s)
919
+ end
920
+
921
+ function _prettify_bigfloat (s:: String ):: String
922
+ mantissa, exponent = split (s, ' e' )
923
+ if ! contains (mantissa, ' .' )
924
+ mantissa = string (mantissa, ' .' )
925
+ end
926
+ mantissa = rstrip (mantissa, ' 0' )
927
+ if endswith (mantissa, ' .' )
928
+ mantissa = string (mantissa, ' 0' )
912
929
end
913
- n = (1 <= x < 10 || - 10 < x <= - 1 || iszero (x)) ? lng - 4 : lng
914
- return String (resize! (buf,n))
930
+ if exponent == " +00"
931
+ mantissa
932
+ else
933
+ string (mantissa, ' e' , exponent)
934
+ end
935
+ end
936
+
937
+ function _string (x:: BigFloat , fmt:: String ):: String
938
+ isfinite (x) || return string (Float64 (x))
939
+ _prettify_bigfloat (string_mpfr (x, fmt))
915
940
end
941
+ _string (x:: BigFloat ) = _string (x, " %.Re" )
942
+ _string (x:: BigFloat , k:: Integer ) = _string (x, " %.$(k) Re" )
943
+
944
+ string (b:: BigFloat ) = _string (b)
916
945
917
946
print (io:: IO , b:: BigFloat ) = print (io, string (b))
918
- show (io:: IO , b:: BigFloat ) = print (io, string (b))
947
+ function show (io:: IO , b:: BigFloat )
948
+ if get (io, :compact , false )
949
+ print (io, _string (b, 5 ))
950
+ else
951
+ print (io, _string (b))
952
+ end
953
+ end
919
954
920
955
# get/set exponent min/max
921
956
get_emax () = ccall ((:mpfr_get_emax , :libmpfr ), Clong, ())
0 commit comments