我正在尝试调试与此特定代码无关的问题,我正在寻找线索,线索是“这个计数器有什么价值?”以下代码行
Warning
输出产生“0.00P”。
以下是我对参数的了解。输入为sprintf(strAtLeast10long, "%lld%c%.02uP",
input/peta, decimal, (long)((input%peta) / (peta/hundred)));
,其值为> =(10 ^ 12 - (10 ^ 7/2))。 unsigned long long
decimal = '.'
是的,我知道static const long long hundred = 100;
static const long long peta = 1000000000000000ULL;
会更好"%lld"
,我会解决这个问题。
但与此同时,我正在寻找有关输入内容的线索。问题发生在客户身上,我们不知道如何重现它,因此添加调试代码或使用调试器不是一种选择。
编译器是IBM z / OS C ++编译器。在你们全都翻白眼之前去“EBCDIC是魔鬼的手工!”它是一个符合Posix的C ++编译器和环境。
答案 0 :(得分:1)
以最直接的方式使用您提供的所有信息,可以得到所描述的输出0.00P
unsigned long long input=999995000000ULL;
(我理解为您给定范围内允许的最低值)
并为
unsigned long long input=9999999999999ULL;
,我认为是指定输出的最高值
可以合理地假设其间的任何值也给出相同的输出。
你得到0.01P
unsigned long long input = 10000000000000ULL;
,这是一个更高的。
这是我的游戏代码,
请检查与您描述的内容是否有任何冲突
(我将格式说明符字符串改编为我的编译器,gcc版本4.9.2(tdm-1),目标:mingw32)。
#include <stdio.h>
int main(void)
{
char decimal='.';
char strAtLeast10long[]=" \0";
static const long long hundred = 100;
static const long long peta = 1000000000000000ULL;
//unsigned long long input= 9999999999999ULL;
//unsigned long long input= 999995000000ULL;
unsigned long long input = 10000000000000ULL;
sprintf(strAtLeast10long, "%I64u%c%.02luP", input/peta, decimal, (long)((input%peta) / (peta/hundred)));
printf("%s\n", strAtLeast10long );
return 0;
}
这个答案与xing的评论一致,后者同时出现了。
答案 1 :(得分:1)
该输出的第一个要求是:
char decimal = '.';
然后范围内的每个input
值:
0 to (1000000000000000ULL/100 - 1)
或同等的
0 to 10^13-1
将字符串设置为:
0.00P
这是因为输入需要低于:
peta/hundred
是1000000000000000ULL/100
由于OP知道输入&gt; =(10 ^ 12 - (10 ^ 7/2)),最终答案是:
input in the range (10^12 - (10^7 / 2)) to 10^13-1 will produce 0.00P
<强>更新强>
在下面的评论中OP改变了对输入的限制,以便输入&gt; =(10 ^ 15 - (10 ^ 7/2))(注意10 ^ 15而不是10 ^ 12与问题不同)。
有了新限制,无输入值可以产生结果0.00P
为了获得第一个0
(来自input/peta
),很明显input
必须小于peta
。
OP的新要求是输入&gt; = peta - 10000000ULL 所以唯一有趣的范围是:
peta - 10000000ULL <= input <= peta - 1
该范围内的所有值都会产生结果0.99P。
结论:对于给定的(新)限制,没有可以产生上述结果的输入值
答案 2 :(得分:1)
有时可以使用蛮力测试。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void foo(unsigned i, unsigned long long input) {
char decimal = '.';
static const long long hundred = 100;
static const long long peta = 1000000000000000ULL;
char strAtLeast10long[10 + 100];
// compile time warnings
sprintf(strAtLeast10long, "%lld%c%.02uP", input / peta, decimal,
(long) ((input % peta) / (peta / hundred)));
if (strcmp("0.00P", strAtLeast10long) == 0) {
printf("%u %llu %s\n", i, input, strAtLeast10long);
fflush(stdout);
}
}
unsigned long long rand_ull(void) {
unsigned long long r = 0;
for (unsigned i = 0; i < sizeof r; i++) {
r *= 256;
r ^= (unsigned) rand();
}
return r;
}
int main(void) {
for (unsigned i = 0; i < 10000000; i++) {
foo(i, rand_ull());
}
return 0;
}
输出
486814 1708844199629 0.00P
984885 8152599175962 0.00P
6266031 209118104328 0.00P
7365558 3983123923889 0.00P
答案 3 :(得分:0)
我通过不相关的路线在爆炸中找到了计数器中的值。它是FWIW 0xFFFFFFFFFFFFFA67或18446744073709550183.舍入代码将其包装为0x0000048c27394a67或4999999998567,它非常小(!),格式为0.00P。
抱歉,我没有更好地描述问题。 10的巨大力量是PITA保持直线和正确输入。