C:quot;的错误输出;(长整型)=(长整型)*(双精度)“;?

C:quot;的错误输出;(长整型)=(长整型)*(双精度)“;?,c,floating-point,double,overflow,multiplication,C,Floating Point,Double,Overflow,Multiplication,这将给出结果:-2147483648 我不知道为什么(这应该是一个积极的结果)。 有人能帮忙吗?也许您必须将这些常量指定为“long-long”文本?e、 g.3289168178315264LLsqrt的参数应为双精度 long long int A = 3289168178315264; long long int B = 1470960727228416; double D = sqrt(5); long long int out = A + B*D; printf("%lld",ou

这将给出结果:-2147483648

我不知道为什么(这应该是一个积极的结果)。
有人能帮忙吗?

也许您必须将这些常量指定为“long-long”文本?e、 g.
3289168178315264LL

sqrt的参数应为双精度

long long int A = 3289168178315264;
long long int B = 1470960727228416;
double D = sqrt(5);

long long int out = A + B*D;

printf("%lld",out);

我猜编译器首先需要将结果从“A+B*D”取整为整数,因为您将结果存储在int字段中。因此,基本上,您遇到了数据类型冲突

A和B仍然是长整型的有效数字,长整型为8字节。您甚至可以将它们乘以1.000,并且仍然具有有效的long int值。在其他一些语言中,它也被称为int64

然而,double也是64位,但其中的一部分用作指数。将一个double与int64相乘时,结果将是另一个double。向其中添加另一个int64仍然可以使其保持双精度。然后将结果再次分配给int64,而不使用特定的舍入方法。如果编译器对此使用4位舍入函数,我不会感到惊讶。我甚至感到惊讶的是,编译器没有吐出和打破对该语句

无论如何,当使用像这样的大数字时,在混合不同类型时必须格外小心。

您的答案(必须验证)计算成功,但是,它会导致符号位溢出,从而使答案为负数。解决方案:使所有变量无符号

原因:

数字以位序列的形式存储在计算机内存中。当设置时,这类序列的第一位表示数字为负数。因此,计算工作正常,但溢出到符号位

建议:


如果你在处理这么大的数字,我建议你买一个多精度算术库T将为您节省大量时间和麻烦。

您使用的是什么编译器/操作系统?我在Windows XP上使用Visual C++ 2008 Express版运行代码,它的工作-答案:6578336356630528(这是一个53位的数字,所以它正好适合在一个双)。 我还尝试了两种变体,以了解操作顺序是否重要:

长整型输出=A; out+=B*D

长整型输出=B*D; out+=A

这两个都很有效


好奇。

它编译时没有错误。在GCC4.0.1和OSX下,编译器抱怨错误:整型常量对于“long”类型来说太大。title还说结果是double,但您的代码说out是long-longint@Mark:add
-std=c99
,它在MacOS X上编译,毫无怨言。@Rohit:您在哪个平台上使用了哪个编译器?你使用了什么选项?事实上,没有LL后缀的GCC甚至抱怨“整型常量对于'long'类型来说太大了”。我在A和B中有正确的值(已经尝试打印它们了)。。。仍然输出不正确。@Rohit On GCC添加LL就可以了。你的编译器是什么?C应该隐式转换为双精度。int-->double是隐式的,但double-->不是。谢谢。。。它适用于“long-long-int-out=A+(long-long-int)(B*D);”作为解释,这没有多大意义。如果代码使用“long long”,那么它应该使用C99编译器。当编译器处理表达式
B*D
时,它必须将B提升为
double
,并将结果计算为
double
。当它查看“A+”时,它看到它必须添加一个
double
和一个
long
,再次将A提升为double并生成一个
double
。然后通过隐式转换将
double
分配给
long
。不应该要求使用普通的
int
甚至
long
。的确,它突然起作用毫无意义。解释起来并不容易,甚至不符合逻辑!要知道原因,您可能需要检查代码的反汇编,以查看它实际创建了什么类型的代码。只是有时候,编译器的行为不合逻辑。在使用GCC4.0.1的MacOS X(10.5.11)上,原始代码生成的答案与Rick所说的MSVC++相同——当我包含
并使用编译器标志
-Wall-Wextra-Wmissing prototype-Wstrict prototype-std=c99
时,编译时没有任何警告(这非常繁琐)。C99编译模式很重要;使用C89模式时,整数常量太大。(附录:在常量中添加
LL
后缀,GCC在C89模式下可以毫无怨言地工作。请注意,添加
-pedantic
会在C89模式下造成麻烦。)你能证明溢出断言的合理性吗?解释你是如何得出溢出发生的结论的。
#include <math.h>
double sqrt( double num );
    long long int A = 3289168178315264;
    long long int B = 1470960727228416;
    double D = sqrt(5.0);
    printf("%f\n",D);
    long long int out = A + (long long) (B * D);
    printf("%lld",out);