Tạm thời thay đổi phương thức làm tròn mà không phải là bất thường và có thể với bin/printf
mặc dù không phải cho mỗi gia nhập bạn cần phải thay đổi nguồn.
Bạn cần các nguồn của coreutils, tôi đã sử dụng phiên bản mới nhất hiện nay là http://ftp.gnu.org/gnu/coreutils/coreutils-8.24.tar.xz .
Giải nén vào một thư mục bạn chọn với
tar xJfv coreutils-8.24.tar.xz
Thay đổi vào thư mục nguồn
cd coreutils-8.24
Tải tệp src/printf.c
vào trình soạn thảo bạn chọn và trao đổi toàn bộ main
chức năng với chức năng sau bao gồm cả hai chỉ thị tiền xử lý để bao gồm các tệp tiêu đề math.h
và fenv.h
. Hàm chính nằm ở cuối và bắt đầu tại int main...
và kết thúc ở cuối tệp với dấu ngoặc đóng}
#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;
}
Chạy ./configure
như sau
LIBS=-lm ./configure --program-suffix=-own
Nó đặt hậu tố -own
ở mọi chương trình con (có rất nhiều) chỉ trong trường hợp bạn muốn cài đặt tất cả và không chắc chắn liệu chúng có phù hợp với phần còn lại của hệ thống không. Coreutils không được đặt tên là dụng cụ cốt lõi mà không có lý do!
Nhưng quan trọng nhất là LIBS=-lm
ở phía trước của dòng. Chúng ta cần thư viện toán học và lệnh này yêu ./configure
cầu thêm nó vào danh sách các thư viện cần thiết.
Chạy đi
make
Nếu bạn có một hệ thống đa lõi / đa bộ xử lý hãy thử
make -j4
trong đó số (ở đây là "4") sẽ đại diện cho số lõi bạn sẵn sàng dành cho công việc đó.
Nếu mọi việc suôn sẻ, bạn có printf
int mới src/printf
. Dùng thử:
BIN_PRINTF_ROUNDING_MODE=1 ./src/printf '%.0f\n' 196.5
BIN_PRINTF_ROUNDING_MODE=2 ./src/printf '%.0f\n' 196.5
Cả hai lệnh sẽ khác nhau ở đầu ra. Các số sau IN_PRINTF_ROUNDING_MODE
trung bình:
- 0 Làm tròn về 0
- 1 Làm tròn về số gần nhất (mặc định)
- 2 Làm tròn về phía vô cực tích cực
- 3 Làm tròn về phía vô cực âm
Bạn có thể cài đặt toàn bộ (không được khuyến nghị) hoặc chỉ sao chép tệp (đổi tên trước đó rất được khuyến khích!) src/printf
Vào một thư mục trong của bạn PATH
và sử dụng như mô tả ở trên.