对于更快的整数输入c,我们可以使用http://abhisharlives.blogspot.in/2012/06/really-fast-io-methods-for-programming.html方法,但如何在c中快速输入浮点数?更快的输入输出的浮点数在c中
回答
使用您提供的链接的想法,我写了自己的快速浮动数字输入技术。下面的代码(包括main()
进行测试):
#include <stdio.h>
#define gc getchar_unlocked
int neg;
int scandigits(double *x, int div) {
register int c = gc();
register double pow10 = 1;
if (x == NULL) {
return -1;
}
*x = 0;
while ((c < '0' || c > '9') && c != '-') {
c = gc();
}
if (c == '-') {
neg = 1;
c = gc();
}
while (!(c < '0' || c > '9')) {
*x *= 10;
*x += (c - '0');
pow10 *= 10;
c = gc();
}
if (neg)
*x = -*x;
if (div)
*x /= pow10;
return c;
}
void scandouble(double *x) {
double left, right = 0;
if (x == NULL) {
return;
}
neg = 0;
int ret = scandigits(&left, 0);
if (ret == '.')
scandigits(&right, 1);
*x = left + right;
}
int main() {
double d;
scandouble(&d);
printf("%f", d);
return 0;
}
注:在一般情况下,最有竞争力的比赛编码不需要快速IO。相反,他们需要更好的算法等。但是,在一些极少数情况下,您需要快速IO才能产生最后0.01s以使您的代码被接受。我只会建议在这种情况下使用这种欺骗(这就是我所说的)。
做了一些测试:当'-'在像'-0.001286'之前的'.'之前得到错误的符号。除此之外,大约52%的时间都像'atof()'那样工作。当它不同时,错误大约是3位的精度。最坏的情况下,大约5位。 (53)。当然,不处理指数符号,INF,NAN。 TBD在'-0.0'和子法线之上。数字靠近'DBL_MAX'失败。 – chux
更正了符号问题。问题存在于范围开放间隔(-1.0,0.0)内的数字。由于代码是用于竞争性编码(其具有非常固定的格式输入并且不需要真正的错误检查),所以不需要处理指数符号,INF,NAN等。 –
经常使用整数运算比double
要快。下面使用整数数学来组成有效数和可选的指数。
double getdouble(void) {
int ch = getchar();
int sign = ch;
if (sign == '-' || sign == '+') {
ch = getchar();
}
long long sum = 0;
int digit_count = 0;
int dp_offset = -1;
int power10 = 0;
int dp = '.';
for (;;) {
while (ch >= '0' && ch <= '9') {
digit_count++;
if (sum < LLONG_MAX/10) {
sum = sum * 10 + ch - '0';
} else {
power10++;
}
ch = getchar();
}
if (ch == dp) {
dp = '0';
dp_offset = digit_count;
ch = getchar();
} else {
break;
}
}
if (dp_offset >= 0) {
power10 -= digit_count - dp_offset;
}
if (ch == 'e' || ch == 'E') {
ch = getchar();
int esign = ch;
if (esign == '-' || esign == '+') {
ch = getchar();
}
int expo = 0;
while (ch >= '0' && ch <= '9') {
expo = expo * 10 + ch - '0';
ch = getchar();
}
if (esign == '-') expo = -expo;
power10 += expo;
}
double y = sum;
if (power10) {
// combine these 2 steps for speed with `pow(10,power10)`.
// leave separate for better handling of very large/very tiny numbers
y *= pow(5, power10); //
y = ldexp(y, power10);
}
if (sign == '-') y = -y;
return y;
}
与atof()
的答案相同86%的时间。
出错时,出现1位错误。
更糟的情况:1位。
句柄指数表示法和子法线,-0.0。
不处理NAN,INF。
返回INF +/-DBL_MAX
,适用于所有较小的值。
你为什么想知道这个? – moffeltje
在许多编码竞争数据中给出的是浮点数。 – Neeraj
你能读二进制吗?这比使用scanf解析文本表单要快得多。 – cup