@@ -166,6 +166,16 @@ function _round_invstep(x, invstep, r::RoundingMode)
166166 return y
167167end
168168
169+ # round x to multiples of 1/(invstepsqrt^2)
170+ # Using square root of step prevents overflowing
171+ function _round_invstepsqrt (x, invstepsqrt, r:: RoundingMode )
172+ y = round ((x * invstepsqrt) * invstepsqrt, r) / invstepsqrt / invstepsqrt
173+ if ! isfinite (y)
174+ return x
175+ end
176+ return y
177+ end
178+
169179# round x to multiples of step
170180function _round_step (x, step, r:: RoundingMode )
171181 # TODO : use div with rounding mode
@@ -186,10 +196,15 @@ function _round_digits(x, r::RoundingMode, digits::Integer, base)
186196 fx = float (x)
187197 if digits >= 0
188198 invstep = oftype (fx, base)^ digits
189- _round_invstep (fx, invstep, r)
199+ if isfinite (invstep)
200+ return _round_invstep (fx, invstep, r)
201+ else
202+ invstepsqrt = oftype (fx, base)^ oftype (fx, digits/ 2 )
203+ return _round_invstepsqrt (fx, invstepsqrt, r)
204+ end
190205 else
191206 step = oftype (fx, base)^- digits
192- _round_step (fx, step, r)
207+ return _round_step (fx, step, r)
193208 end
194209end
195210
0 commit comments