Das vorübergehende Ändern der Rundungsmodi ist nicht ungewöhnlich und es ist möglich, bin/printf
dass Sie die Quellen ändern müssen, obwohl dies per se nicht der Fall ist.
Sie benötigen die Quellen der Coreutils. Ich habe die neueste Version verwendet, die heute verfügbar ist: http://ftp.gnu.org/gnu/coreutils/coreutils-8.24.tar.xz .
Entpacken Sie mit in ein Verzeichnis Ihrer Wahl
tar xJfv coreutils-8.24.tar.xz
Wechseln Sie in das Quellverzeichnis
cd coreutils-8.24
Laden Sie die Datei src/printf.c
in den Editor Ihrer Wahl und tauschen Sie die gesamte main
Funktion mit der folgenden Funktion aus, einschließlich der beiden Präprozessoranweisungen, um die Headerdateien math.h
und einzuschließen fenv.h
. Die Hauptfunktion befindet sich am Ende und beginnt int main...
und endet am Ende der Datei mit der schließenden Klammer}
#include <math.h>
#include <fenv.h>
int
main (int argc, char **argv)
{
char *format;
char *rounding_env;
int args_used;
int rounding_mode;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
atexit (close_stdout);
exit_status = EXIT_SUCCESS;
posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
// accept rounding modes from an environment variable
if ((rounding_env = getenv ("BIN_PRINTF_ROUNDING_MODE")) != NULL)
{
rounding_mode = atoi(rounding_env);
switch (rounding_mode)
{
case 0:
if (fesetround(FE_TOWARDZERO) != 0)
{
error (0, 0, _("setting rounding mode to roundTowardZero failed"));
return EXIT_FAILURE;
}
break;
case 1:
if (fesetround(FE_TONEAREST) != 0)
{
error (0, 0, _("setting rounding mode to roundTiesToEven failed"));
return EXIT_FAILURE;
}
break;
case 2:
if (fesetround(FE_UPWARD) != 0)
{
error (0, 0, _("setting rounding mode to roundTowardPositive failed"));
return EXIT_FAILURE;
}
break;
case 3:
if (fesetround(FE_DOWNWARD) != 0)
{
error (0, 0, _("setting rounding mode to roundTowardNegative failed"));
return EXIT_FAILURE;
}
break;
default:
error (0, 0, _("setting rounding mode failed for unknown reason"));
return EXIT_FAILURE;
}
}
/* We directly parse options, rather than use parse_long_options, in
order to avoid accepting abbreviations. */
if (argc == 2)
{
if (STREQ (argv[1], "--help"))
usage (EXIT_SUCCESS);
if (STREQ (argv[1], "--version"))
{
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
(char *) NULL);
return EXIT_SUCCESS;
}
}
/* The above handles --help and --version.
Since there is no other invocation of getopt, handle '--' here. */
if (1 < argc && STREQ (argv[1], "--"))
{
--argc;
++argv;
}
if (argc <= 1)
{
error (0, 0, _("missing operand"));
usage (EXIT_FAILURE);
}
format = argv[1];
argc -= 2;
argv += 2;
do
{
args_used = print_formatted (format, argc, argv);
argc -= args_used;
argv += args_used;
}
while (args_used > 0 && argc > 0);
if (argc > 0)
error (0, 0,
_("warning: ignoring excess arguments, starting with %s"),
quote (argv[0]));
return exit_status;
}
Führen Sie ./configure
wie folgt aus
LIBS=-lm ./configure --program-suffix=-own
Das Suffix wird -own
bei jedem Unterprogramm eingefügt (es gibt viele), nur für den Fall, dass Sie alle installieren möchten und nicht sicher sind, ob sie zum Rest des Systems passen. Die Coreutils werden nicht ohne Grund als Core Utils bezeichnet!
Aber das Wichtigste ist das LIBS=-lm
vor der Linie. Wir brauchen die mathematische Bibliothek und dieser Befehl weist Sie ./configure
an, sie der Liste der benötigten Bibliotheken hinzuzufügen.
Führen Sie make aus
make
Wenn Sie ein Multicore- / Multiprozessorsystem haben, versuchen Sie es
make -j4
Dabei sollte die Zahl (hier "4") die Anzahl der Kerne darstellen, die Sie für diesen Job bereit haben.
Wenn alles gut gegangen ist, haben Sie den neuen printf
Int src/printf
. Versuch es:
BIN_PRINTF_ROUNDING_MODE=1 ./src/printf '%.0f\n' 196.5
BIN_PRINTF_ROUNDING_MODE=2 ./src/printf '%.0f\n' 196.5
Beide Befehle sollten sich in der Ausgabe unterscheiden. Die Zahlen nach IN_PRINTF_ROUNDING_MODE
bedeuten:
- 0 Rundung gegen 0
- 1 Rundung auf die nächste Zahl (Standard)
- 2 Rundung in Richtung positive Unendlichkeit
- 3 Rundung gegen negative Unendlichkeit
Sie können das Ganze installieren (nicht empfohlen) oder einfach die Datei (vorheriges Umbenennen wird dringend empfohlen!) src/printf
In ein Verzeichnis in Ihrem kopieren PATH
und wie oben beschrieben verwenden.