From c108d8ecc65c8e9626ce782213764d5d12508b43 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 17 Sep 2019 03:54:41 -0700 Subject: =?UTF-8?q?Don=E2=80=99t=20round=20file-system-info=20counts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * src/fileio.c (blocks_to_bytes): Convert the byte count to an integer, since we have bignums now. This avoids possible rounding errors for file systems containing more than 8 PiB or so. --- src/fileio.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/fileio.c b/src/fileio.c index c129f19872e..81c29ca0cca 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -6081,16 +6081,18 @@ effect except for flushing STREAM's data. */) #ifndef DOS_NT -/* Yield a Lisp float as close as possible to BLOCKSIZE * BLOCKS, with - the result negated if NEGATE. */ +/* Yield a Lisp number equal to BLOCKSIZE * BLOCKS, with the result + negated if NEGATE. */ static Lisp_Object blocks_to_bytes (uintmax_t blocksize, uintmax_t blocks, bool negate) { - /* On typical platforms the following code is accurate to 53 bits, - which is close enough. BLOCKSIZE is invariably a power of 2, so - converting it to double does not lose information. */ - double bs = blocksize; - return make_float (negate ? -bs * -blocks : bs * blocks); + intmax_t n; + if (!INT_MULTIPLY_WRAPV (blocksize, blocks, &n)) + return make_int (negate ? -n : n); + Lisp_Object bs = make_uint (blocksize); + if (negate) + bs = CALLN (Fminus, bs); + return CALLN (Ftimes, bs, make_uint (blocks)); } DEFUN ("file-system-info", Ffile_system_info, Sfile_system_info, 1, 1, 0, -- cgit v1.2.1