libtom / libtommath

LibTomMath is a free open source portable number theoretic multiple-precision integer library written entirely in C.
https://www.libtom.net
Other
656 stars 194 forks source link

Print big integers with (f)printf #551

Open czurnieden opened 1 year ago

czurnieden commented 1 year ago

Simple implementation of a big integer extension to printf(3)

czurnieden commented 1 year ago

Variation of #550 following a suggestion by @sjaeckel . GLibC only. This is only the bare minimum, more to come but the documentation about printf.h is sparse&mdash&more or less: "See the source". Odd errors incoming. Hu?

czurnieden commented 1 year ago

Failure of mp_log is unsanitized input. Can happen if you use a PRNG for the input ;-) Needs a check, will add it tommorow.

The other one "/home/runner/work/libtommath/libtommath/demo/test.c:382: undefined reference to `mp_printf_extension'" needs a bit more work, I'm afraid.

czurnieden commented 1 year ago

I broke it?

czurnieden commented 1 year ago

Rebased to hide all of the pain ;-) Had to install a dummy function for MSVC but that is not how it should be done. At least I hope that that is not how it should be done but I am no expert in that regard. Any ideas?

czurnieden commented 1 year ago

The problem with the unchecked input for mp_log tests mentioned above is in #552 .

czurnieden commented 1 year ago

These are prefix modifiers like ll or z. It is not possible (Might possible but I have not found a way to do so) to use the common specifiers, so things like %Nx for hexadecimal or %No for octal do not work, sadly, it is %kN and %rN respectively.

Prefixes of the printed numbers are:

Most letters of the English alphabet, both upper and lower case, are already taken by printf(3)'s format.

The modifiers can be more than one character, so something like "b16N" or "b64N" would come handy but the letter "b" might get taken by C2x for binary representation. Digits without anything else are possible, too. It is quite easy to change, so don't be shy and tell me if you hate my idea and prefer e.g.: the bxxN style.

BTW: the way it works is that for every modifier one bit of a short is set, so there is no way to implement all 62 possible bases.

The modifier accepting function takes wchar_t * but I would refrain from using unicode, more trouble than it's worth.

Not implemented are:

This function is not thread safe! But who would expect thread safety from a printf anyways?

The functions to print a single limb and the raw limb-array (a.dp) are not yet implemented.

czurnieden commented 1 year ago

No, that is way to much effort to print a simple native integer, there must be a simpler way to do it. Or at least without the heavy artillery (sprintf) I used.

czurnieden commented 1 year ago

Conflict is an empty line in tommath.h? Hu?

czurnieden commented 1 year ago

@sjaeckel I saw that I forgot to add MP_31BIT tests to #549 Kept that commit separate and at the end if it is wanted.

Phew, took by far more time to write the tests for all our optional flavours than to write the actual code! ;-)

But that is what the GLibC printf-extension is able to do: print the big integer, one limb and the limb-array in all useful bases and the formatting that printf offers (sans the thousand-separators, don't think it is a good idea to start meddling with locales, but maybe an underbar for all locales, a space (U+2009?) maybe?).

The documentation is a bit sparse for now. I'll check later.

The extension allows for some more fiddling. It is, for example, possible to set the padding character (a wchar_t so one can have some fun with it).

mp_printf_extension_init takes no arguments now, but could take e.g.: a string with a list of the specifiers that are wanted (might get complicated with mp_printf_extension_clear if there are different/more specifiers given than those that get unregistered by default).