]> git.eshelyaron.com Git - emacs.git/commitdiff
Don’t round file-system-info counts
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 17 Sep 2019 10:54:41 +0000 (03:54 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 17 Sep 2019 10:55:12 +0000 (03:55 -0700)
* 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

index c129f19872e1fc928af14a9f8cb8ecc70d7c1b93..81c29ca0cca4d587fdcc485226e7f1b26554941a 100644 (file)
@@ -6081,16 +6081,18 @@ effect except for flushing STREAM's data.  */)
 \f
 #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,