gpt4 book ai didi

c - 面临寻找大数立方体的问题

转载 作者:太空宇宙 更新时间:2023-11-04 05:32:14 25 4
gpt4 key购买 nike

我有这20个数字

409,29,657,523,1481,447,904,312,110,1207,55,284,65,232,102,206,218,565,731,34 

而且他们是大众,我需要找到 $m^{3}$ 的平均值。但它给了我错误的答案。当我在一些限制后添加它们时,总和下降。所以我试图在添加每个立方体后打印总和 mmmsum = mmmsum +m*m*m;

首先我尝试使用 int 数据类型 (%d) 并观察到总和下降,然后假设这可能是由于范围的限制我尝试了 unsigned int 然后我也遇到了同样的问题问题,所以我尝试了 unsigned long int 同样的问题,但只是金额更高,然后我尝试了 unsigned long long,这次总和在某一时刻超过了预期,在两次总和之后它再次下降

    int main()
{
int m[] ={409,29,657,523,1481,447,904,312,110,1207,55,284,65,232,102,206,218,565,731,34};
int mmmsum=0;

for(int i=0;i<20;i++)
{
mmmsum = mmmsum + m[i]*m[i]*m[i];
printf("\n %d",mmmsum);
}

return 0;
}

现在,如果我使用 pow 函数计算立方体和 unsigned long int (%lu) 数据类型,它就正确了。为什么它不适用于 m*m*m

我上面显示的代码是我写的用于解码的代码:我正在发布一段原始代码,实际上数组 a 并不存在真正的问题

    unsigned long long m_av,mm_av,mmm_av;
........
//======= for M, MM, MMM =============
m_av=0;mm_av=0;mmm_av=0;
cluster = head;
while(cluster)
{
l = cluster->label;
m = L2[l];
m_av = m_av + m;
mm_av = mm_av + m*m;
mmm_av = mmm_av+ pow(m,3);

cluster = cluster->next_L;
}
m_av = m_av/Tnc;
mm_av = mm_av/Tnc;
mmm_av = mmm_av/Tnc;

//===================================
fprintf(fp,"%lu\t%lf\t%d\t%llu\t%llu\t%llu etc.....\n",t_step,E,Tnc,m_av,mm_av,mmm_av,m_max,etc.....);

在我总共有 100,000 个粒子的模拟中,我正在为这段代码如下所示放置

373926  0.225469    6   25000   48820678    109937352837987 . . .   
392623 0.225469 6 25000 48820678 109937352837987 . . .
412254 0.205942 4 37500 194892454 179871291607140 . . .
432867 0.205942 4 37500 194892454 179871291607140 . . .
454510 0.205942 4 37500 194892454 179871291607140 . . .
477235 0.020043 3 50000 6148914690883261936 664306051917360 . .
501097 0.020043 3 50000 6148914690883261936 664306051917360 . .
526152 0.020043 3 50000 6148914690883261936 664306051917360 . .
552459 0.020043 3 50000 6148914690883261936 664306051917360 . .
580082 0.020043 3 50000 6148914690883261936 664306051917360 . .
609087 0.020043 3 50000 6148914690883261936 664306051917360 . .
639541 0.002030 2 75000 702942377 1247147318025000 . . .
671518 0.002030 2 75000 702942377 1247147318025000 . . .
705094 0.002030 2 75000 702942377 1247147318025000 . . .
740348 0.002030 2 75000 702942377 1247147318025000 . . .

我觉得这跟这个问题有关系-> C : Printing big numbers

最佳答案

1481 * 1481 * 1481 = 3 248 367 641,不适合 signed int (提供 32 位,不一定如此),其最大值为 2 147 483 647,因此会发生溢出(对于 signed 整数类型,这是未定义的行为!)。

I have tried unsigned int, unsigned long and unsigned long long.

所有这些都应该足够大(对于 32 位,范围最大为 4 294 967 295)。实际上,来自 <stdint.h> 的类型(例如 uint64_t )更可取,因为它们具有保证的位宽。

无论如何,问题是:您在哪里尝试过?将数组 的基础类型更改为这些更大的类型将立即消除问题(前提是您也更改了 mmmsum 的类型)。

如果您想要或需要(无论出于何种原因)保留 int数组,那么你需要将你的操作数转换为更大的类型,否则 m * m * m仍将计算在(太小)int .所以:

uint64_t mmmsum = 0;
// ...
mmmsum += static_cast<uint64_t>(m[i]) * m[i] * m[i];

仅转换第一个参数就足够了,因为其他参数随后将被隐式提升(转换)。

使用 pow做一些非常相似的事情:由于函数参数是 double 类型,int值也会在 计算之前进行转换,并且 double 足够大以保存相关值。但是, double 计算会引入舍入误差,使用 pow即使您使用整数值。有时结果会(至少)小于实际值,然后当转换回积分时,您会得到一个错误的值(太小了)。如果仅使用整数值,如在给定的情况下,在回退之前添加 0.5 已经解决了问题......

关于有符号/无符号的旁注:不要决定范围的一位是有符号的还是无符号的——如果您需要更大的范围,请切换到下一个更大的数据类型。关于使用有符号或无符号的决定只能由有意义或无意义的负值决定(在您的情况下显然是后者)。

关于c - 面临寻找大数立方体的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58637646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com