cout in C++ interface prints wrong exponents for sufficiently big numbers
Klaus Frahm
frahm at irsamc.ups-tlse.fr
Mon May 11 12:22:37 CEST 2026
This bug report concerns the C++ interface of
GMP versions 6.x.x, 5.1 and probably also others before.
It contains an attached test program, two output files from
the test program, an error description, a suggested patch and
link to an old related bug report from 2009 (the later only for information).
The issue is shown by the attached test program. The test program does
not take any arguments. It computes the
and prints in 2+2 ways (cout/general ofstream and gpm_printf/gpm_fprintf)
(as mpf_class) the double powers: 2^(2^i) for i=0,...,39.
It also produces two (simple and short) output files, also attached to this mail.
When i is larger than 32 (i.e. exponent larger than int) cout and ofstream show
wrong exponents (eventually with negative sign) while the gpm_printf
output is correct. This is related to the fact that the gmp float exponent
_mp_exp is of the same size as long (8 bytes; at least on the different linux 64 bit systems
where I verified this bug) but the print format for the exponent is still of the form "%d"
and not "%ld" in the file cxx/osfuns.c.
The problem can be solved by the patch (applied to cxx/osfuns.c):
--- osfuns_orig.cc 2026-05-11 00:43:19.788741882 +0200
+++ osfuns.cc 2026-05-11 00:44:21.706742961 +0200
@@ -60,12 +60,12 @@
{printf/doprnt.c
if ((o.flags() & ios::basefield) == ios::hex)
{
- p->expfmt = "@%c%02d";
+ p->expfmt = "@%c%02ld";
p->base = (o.flags() & ios::uppercase ? -16 : 16);
}
else
{
- p->expfmt = (o.flags() & ios::uppercase ? "E%c%02d" : "e%c%02d");
+ p->expfmt = (o.flags() & ios::uppercase ? "E%c%02ld" : "e%c%02ld");
if ((o.flags() & ios::basefield) == ios::oct)
p->base = 8;
else
This patch is for gmp-6.1.2 but it should be the same for 6.3 (maybe with different line numbers)
and other versions. As can be seen it simply replaces %02d by %02ld in three places where the format p->expfmt is defined.
I have tested that with this patch the problem is solved (on different computers and different gmp version 6.1.2 and 6.3).
By the way, the bug is also related to an old bug report from 2009 for the same issue in the
family of gmp_printf functions (which are now okay for this !):
https://gmplib.org/list-archives/gmp-bugs/2009-June/001530.html
where a similar patch for the file printf/doprnt.c was suggested.
In the actual GMP version this file is now correct (using the %ld format for the exponent). I suppose this is due to the
old bug report.
Yours sincerely,
Klaus Frahm.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cout_bug.cc
Type: text/x-c++src
Size: 781 bytes
Desc: not available
URL: <https://gmplib.org/list-archives/gmp-bugs/attachments/20260511/12685f94/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cout_test.dat
Type: application/ms-tnef
Size: 1421 bytes
Desc: not available
URL: <https://gmplib.org/list-archives/gmp-bugs/attachments/20260511/12685f94/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gmp_printf_test.dat
Type: application/ms-tnef
Size: 1625 bytes
Desc: not available
URL: <https://gmplib.org/list-archives/gmp-bugs/attachments/20260511/12685f94/attachment-0002.bin>
More information about the gmp-bugs
mailing list