【问题标题】:Problems with long double in gcc 4.6.1 (linux)gcc 4.6.1 (linux) 中的 long double 问题
【发布时间】:2012-06-06 03:37:14
【问题描述】:
#include <stdio.h>

int main()
{
    long double n = (long double)1208925819614629174706175; // (1<<80)-1 (generated in python)
    printf("%LG\n",n);
}

使用 gcc 编译时,我收到警告

test.c:5:31: warning: integer constant is too large for its type [enabled by default]

在运行时打印-1

在执行sizeof(long double) 时,它会打印12。 所以签名的long double 应该容纳 (1 对吧?

如何让它正常工作?

PS:我正在处理的原始问题是处理存储大至 12*(1018) 的有符号整数。我不想编写乘法、加法和其他计算例程。那我该怎么做呢?

【问题讨论】:

  • “我处理的原始问题是存储带符号的整数。”你知道long double 不是整数类型吗?
  • 我才意识到!好吧,你能建议一些方法,以便我可以存储 12*(10**18) 而不使用数组作为数字吗?是否存在任何方法?
  • Long double 将处理 10**300 及以上,这不是编译器所抱怨的。它表示您尝试转换为 long 的整数对于整数来说太大了。 (提示 - 添加小数点)
  • 如果你想存储最多 12*(10^18) 的整数,为什么不使用unsigned long long,它最多可以存储~18*(10^18)。你可能想使用常量类型说明符,像这样:1.5f (float), 100ll (long long)
  • @saeedn 我已经尝试过unsigned long long,但无济于事。不管怎样,看来我得自己想办法了!

标签: c gcc type-conversion linux-mint


【解决方案1】:

Long double 将处理 10**300 及以上,这不是编译器所抱怨的。它表示您尝试转换为 long 的整数对于整数来说太大了。 (提示 - 添加小数点)– starbolin

【讨论】:

    【解决方案2】:

    Starbolin 是正确的,但我认为需要对这个表达式进行详细解释:

    在 C 中,数字常量(不带小数点)的类型为 intlong,具体取决于值。
    您使用的常量1208925819614629174706175long 来说也太大了,所以它被截断了。
    所有这些都发生在转换为 long double 并分配给 n 之前。
    当浮点类型进入画面时,数值常量已经被截断,丢失的位再也回不来了。

    这是因为 C 是一种简单的语言,它在编译期间遵循简单定义的步骤。编译器不会“窥视”数字常量将被强制转换为long double。它首先将其视为long,然后继续。

    【讨论】:

    • long long,从 C99 开始。如果它们有后缀U,或者以十六进制或八进制形式给出,则将无符号类型添加到可能性中(L 后缀从可能性)。
    • @DanielFischer,你是对的,但我尽量保持简单。另一个奇怪的地方是3*10^9int(虽然对于int 来说太大了),而5*10^9long(或long long)。
    • 以为您会意识到这一点,但觉得有义务完成列表。对我来说printf("%zu\n",sizeof 3000000000); 打印 8,所以这里是long,而不是int (gcc-4.5.1)。哪个编译器说它是int
    • gcc 4.3.3,带默认标志(但不带 -std=c99)。
    • 奇数。即使使用-std=c89(或没有任何标志),我也应该得到 8 个尺寸。是 32 位系统还是 64 位系统?
    猜你喜欢
    • 2012-01-12
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 2019-06-09
    • 1970-01-01
    • 2014-09-30
    • 2011-07-09
    相关资源
    最近更新 更多