diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index fbdd83fa86ed033d4fcbd632cb3edc977d90b8a5..cae8babcb40bf0e3b8ac9521f26d26b32dfb2216 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -191,19 +191,19 @@ on 64-bit platforms.
@cindex integer range
@cindex number of bignum bits, limit on
@defvar integer-width
-The value of this variable is a nonnegative integer that is an upper
-bound on the number of bits in a bignum. Integers outside the fixnum
-range are limited to absolute values less than
+The value of this variable is a nonnegative integer that controls
+whether Emacs signals a range error when a large integer would be
+calculated. Integers with absolute values less than
@ifnottex
2**@var{n},
@end ifnottex
@tex
@math{2^{n}},
@end tex
-where @var{n} is this variable's value. Attempts to create bignums outside
-this range signal a range error. Setting this variable
-to zero disables creation of bignums; setting it to a large number can
-cause Emacs to consume large quantities of memory if a computation
+where @var{n} is this variable's value, do not signal a range error.
+Attempts to create larger integers typically signal a range error,
+although there might be no signal if a larger integer can be created cheaply.
+Setting this variable to a large number can be costly if a computation
creates huge integers.
@end defvar
diff --git a/src/alloc.c b/src/alloc.c
index 5c5b56d02e9a2d41139aa69325cf51bac687173a..64aaa8acdfa75d6110bcca707964221fdc9e39c6 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -7369,9 +7369,9 @@ The time is in seconds as a floating point value. */);
doc: /* Accumulated number of garbage collections done. */);
DEFVAR_INT ("integer-width", integer_width,
- doc: /* Maximum number of bits in bignums.
-Integers outside the fixnum range are limited to absolute values less
-than 2**N, where N is this variable's value. N should be nonnegative. */);
+ doc: /* Maximum number N of bits in safely-calculated integers.
+Integers with absolute values less than 2**N do not signal a range error.
+N should be nonnegative. */);
defsubr (&Scons);
defsubr (&Slist);
diff --git a/src/bignum.c b/src/bignum.c
index 009d73118c29369d2737399a1f9c89a2135ea2c2..3883d3a39446cbc1db587f764858107a08e83418 100644
--- a/src/bignum.c
+++ b/src/bignum.c
@@ -82,8 +82,11 @@ static Lisp_Object
make_bignum_bits (size_t bits)
{
/* The documentation says integer-width should be nonnegative, so
- a single comparison suffices even though 'bits' is unsigned. */
- if (integer_width < bits)
+ comparing it to BITS works even though BITS is unsigned. Treat
+ integer-width as if it were at least twice the machine integer width,
+ so that timefns.c can safely use bignums for double-precision
+ timestamps. */
+ if (integer_width < bits && 2 * max (INTMAX_WIDTH, UINTMAX_WIDTH) < bits)
overflow_error ();
struct Lisp_Bignum *b = ALLOCATE_PLAIN_PSEUDOVECTOR (struct Lisp_Bignum,