[Rd] sprintf of big int

Tomek Gieorgijewski cybergeorge2020 @end|ng |rom gm@||@com
Tue May 12 13:04:40 CEST 2026


Hi!

My first thought was that it may be possible as there is already coercion
for numeric vectors to int if some conditions ("exactlyInteger")
are met. Here is the code of Internal sprintf in that matter:
 case 'x':
 case 'X':
          if(TYPEOF(_this) == REALSXP) {
              // qdapTools manages to call this with NaN
              Rboolean exactlyInteger = TRUE;
              R_xlen_t i = 0;
              R_xlen_t n = XLENGTH(_this);
              for(i = 0; i < n; i++) {
                  double r = REAL(_this)[i];
                  if (R_IsNA(r)) continue; // NA_REAL is ok
                  if (!R_FINITE(r) || (double)((int) r) != r) {
                      exactlyInteger = FALSE;
                      break;
                  }
               }
              if(exactlyInteger)
              _this = coerceVector(_this, INTSXP);
               PROTECT(a[nthis] = _this);
               nprotect++;
           }
         break;

But the idea here is to coerce to INTSXP and then do formatting, so it
won't store bigger integers than 31 bits.
And without coercion we may need to wait for 64bit integers in R or change
the further part of the code for
REALSXP where we add separate part for "%x" format and check if it's pure
integer stored in numeric:
case REALSXP:
                              {
                                  double x = REAL(_this)[ns % thislen];
                                  if (checkfmt(fmtp, "aAfeEgG"))
                                      error(_("invalid format '%s'; %s"),
fmtp,
                                            _("use format %f, %e, %g or %a
for numeric objects"));
                                 if (R_FINITE(x)) {
                                     _my_sprintf(x)
                                  } else { // ....and so on
I guess changing _my_sprintf macro would also be involved as it is based on
snprintf and generally "%x" format does not allow double/floats.
But that's only my first attempt at analyzing sprintf function. The file
sprintf.c has ~500 lines of code and even more subtleties one must
understand to change the function.

So if you really need bigger ints to be shown as hex, I propose you
implement your own R function to print such thing.
Start with dividing by 16 iteratively and checking the modulo for proper
hex character.

T.

wt., 12 maj 2026 o 09:38 Sokol Serguei via R-devel <r-devel using r-project.org>
napisał(a):

> Hi,
>
> I wanted to print a big integer value in hexadecimal format with sprintf()
> but could not (cf. here
> after). As R supports integer values upto 2**53-1 (storing them in a
> double) is it possible to make
> sprintf() to work on such big values?
>
> Best,
> Serguei.
>
>  > sprintf("%x", 2**31-1)
> [1] "7fffffff"
>  > sprintf("%x", 2**31)
> Error in sprintf("%x", 2^31) :
>    invalid format '%x'; use format %f, %e, %g or %a for numeric objects
>  > sessionInfo()
> R version 4.6.0 (2026-04-24)
> Platform: x86_64-pc-linux-gnu
> Running under: Linux Mint 21.1
>
> Matrix products: default
> BLAS/LAPACK: /opt/OpenBLAS/lib/libopenblas_nonthreaded_haswell-r0.3.27.so;
> LAPACK version 3.12.0
>
> locale:
> [1] C
>
> time zone: Europe/Paris
> tzcode source: system (glibc)
>
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods  base
>
> loaded via a namespace (and not attached):
> [1] compiler_4.6.0
>
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

	[[alternative HTML version deleted]]



More information about the R-devel mailing list