提问人:KJ7LNW 提问时间:10/28/2023 最后编辑:John KugelmanKJ7LNW 更新时间:10/28/2023 访问量:96
如何在不更改格式说明符的情况下同时支持双精度和长双精度?
How do you support both doubles and long doubles without changing format specifiers?
问:
我能够通过简单地搜索替换 来使用 's 编译 xnec2c。它计算正确,除非使用格式说明符的任何地方,因为它想要......当然,GCC 在用这句话入侵它之后,正在吠叫很多:long double
double
long double
%Lf
-Wformat=
perl -p -i -e 's/_Complex/complex/g; s/gdouble/double/g; s/([ \t(]|^)double/$1long double/g' src/*.[ch]
最终目标是:
- 将所有 替换为
double
typedef double xnec2c_double_t
- 提供一个选项,将 typedef 调整为 .
./configure --enable-long-double
configure.ac
long double
- 不破坏 ' 和相关的基于格式说明符的函数(如 等)。
printf
sprintf
问题:
通过更改 ?double
long double
typedef
我可以在每个打印件周围加上 ',或者和字符串连接在一起,但这似乎几乎和在每个 .如果有一种优雅的方法可以做到这一点,宏可能是一种选择,但我还没有想出一个。#ifdef
#define SPEC_DOUBLE "%Lf"
printf("foo=" SPEC_DOUBLE "\n", foo)
#ifdef
printf
my_smart_printf
有没有“好”的方法可以做到这一点?
注意:
- 我宁愿不切换到 C++。
- 这个问题与autoconf无关。
- 我是xnec2c的维护者。
答:
2赞
chux - Reinstate Monica
10/28/2023
#1
如何在不更改 C 格式说明符的情况下同时支持双精度和长双精度?
将浮点参数转换为并使用匹配说明符,以便在所有情况下都可以使用相同的格式。
long double
long double
printf("%Lf\n", (long double) float_or_double_or_long_double_object);
按照 中的示例并创建自己的说明符,如 .注意没有。
PRI...
<inttypes.h>
#define SPEC_DOUBLE "Lf"
"%"
printf("%" SPEC_DOUBLE "\n", xnec2c_double_object);
创建一个帮助程序函数,将特殊浮点转换为字符串。
extern char *xnec2c_to_str(char *dest, xnec2c_double_t x); // - digits . frac \0 #define xnec2c_STR_SZ (1 + (LDBL_MAX_10_EXP+1) + 1 + 6 + 1) #define xnec2c_TO_STR(x) (xnec2c_to_str((char[xnec2c_STR_SZ]){ 0 }, x) printf("%s\n", xnec2c_TO_STR(x));
评论
L
printf("%Lf\n", (long double) double_or_long_double_object);
#define SPEC_DOUBLE "%Lf"
PRI
#define SPEC_DOUBLE "Lf"
scanf()
printf()
<inttypes.h>
PFX_PRIG_typedefname
PFX_SCNf_typedefname
typedefname
PRI_G_typedefname
#define PFX_PRIG_typedefname "LG"
long double
#define PFX_SCNf_typedefname "lf"
double
printf()
scanf()
"%lf"
double
printf()
"%f"
double
SPEC_DOUBLE
是我个人在这种情况下使用的。但是,我也这样做:with:并在需要时使用它,使用诸如代替和(例如)或代替的宏进行调整。然后只有函数必须改变。printf("%s\n",print_double(whatever));
const char *print_double(double val) { static char buf[100]; sprintf(buf,"%f",val); return buf; }
long double
SPEC_DOUBLE
%f
typedef long double TYPE_DOUBLE;
#define TYPE_DOUBLE long double
double