为什么这个数字停滞不前了?
Why the number stuck and doesn't increase anymore?
首先,我是编程新手。
这对我来说只是一个简单有趣的项目,但我遇到了意想不到的问题,我不知道为什么。
背景:有点像《土拨鼠之日》,从一个月开始循环,到下一个循环时间减少一秒。我正在尝试计算总年数(通过计算总秒数)。
这是我的代码:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int loop=1;
double secondsInDay = 60*60*24; //86400
double secondsInMonth = 86400*30; //2592000
float secondsInLoop = 86400*30;
double totalYears = 0;
long totalSeconds = 0;
cout <<"Loop : "<<loop<<endl;
totalSeconds += secondsInLoop;
cout <<"-> Total seconds: "<<totalSeconds<<endl;
cout <<fixed<<setprecision(0)<<"-->Total time in this Loop: "<<secondsInLoop;
cout <<fixed<<setprecision(3)<<" seconds / "<<secondsInLoop/60<<" minutes / "<<secondsInLoop/3600<<" hours / "<<secondsInLoop/86400<<" days"<<endl<<endl;
while (secondsInLoop>0)
{
if (loop%1000==0)
{
cout <<"Loop: "<<loop<<endl;
cout <<"-> Total Seconds: "<<totalSeconds<<endl;
cout <<fixed<<setprecision(0)<<"-->Total time in this Loop: "<<secondsInLoop;
cout <<fixed<<setprecision(3)<<" seconds / "<<secondsInLoop/60<<" minutes / "<<secondsInLoop/3600<<" hours / "<<secondsInLoop/86400<<" days"<<endl;
totalYears = totalSeconds/(secondsInMonth*12); //31104000
cout <<fixed<<setprecision(3)<<"-->> Total Years: "<<totalYears<<endl<<endl;
}
totalSeconds = totalSeconds+secondsInLoop;
secondsInLoop--;
loop++;
}
cout <<"Loop: "<<loop<<endl;
cout <<"#-> Total Seconds: "<<totalSeconds<<endl;
totalYears = totalSeconds/(secondsInMonth*12); //31104000
cout <<"#->> Total Years: "<<totalYears<<endl<<endl;
return 0;
}
问题:在我的代码中,在大约循环 2461000 中,Total Seconds 被卡住了,不再增加。
奇怪的是,卡住的数字是3359234850816,距离long类型的最大数字还差得很远。
而且,如果我尝试正常计算(在另一个简单的算术代码中),就不会像那样卡住。
有人可以帮忙吗?
此外,我愿意接受任何关于整理它的建议,或任何与此相关的建议。谢谢
您已经超出了所选数字表示的限制。
这可能令人惊讶,因为大多数时候,当混合数字类型时,C++ 将转换为最能表示结果的类型。例如,将int
和long long
相加计算为long long
。添加一个float
和double
计算为一个double
。但是,您通过添加整数类型和 float
.
选择了一条奇怪的路线
由usual arithmetic conversions,将任意整数类型和一个float
相加计算为一个float
。任何整数类型。如果您碰巧有一个 128 位 long long
和一个 32 位 float
,将它们相加会产生一个 32 位 float
。 float
被视为可以更好地表示数字,这是有好处的。典型的 32 位 float
确实具有与 128 位整数大致相同的 运行ge,具有能够表示非整数的好处。然而,虽然这种想法可能落后于规则,但规则只是 float
与整数类型组合产生 float
.
将此应用于更新 totalSeconds
.
的行
totalSeconds = totalSeconds+secondsInLoop;
虽然 totalSeconds
是 long
,但 secondsInLoop
是 float
。这意味着当这些相加时,结果是 float
。据推测,这意味着一个 32 位值在有效数中有 24 个逻辑位(23 个实数位加上假定的 1)。这是结果的精度。仅保留总和的最高有效 24 位。当你的值停止增加时,整数是 3359234850816
而浮点值是 131071
(我 运行 你的代码想出这个)。这些值的比例是25629124
,一个25位的值。与totalSeconds
相比,secondsInLoop
的价值如此之小,就float
加法而言,还不如为零呢
要获得正确的计算,您需要更改结果的类型。最直接的方法是对所有整数值使用 long
,只记得在除法之前转换为浮点数。另一种方法是将 secondsInLoop
更改为 double
(就像您的其他保存整数的浮点变量一样 - 奇怪的是您选择了这个)。由于典型的 double
具有 53 位逻辑精度,因此它可以精确表示所有 32 位整数。因此,避免了这个问题(直到您需要转到 64 位整数...)。您还可以在总和中转换为整数类型,这会覆盖到浮点数的转换。
所以
long secondsInLoop = 86400*30;
或
double secondsInLoop = 86400*30;
或
totalSeconds = totalSeconds + static_cast<long>(secondsInLoop);
可以更精确地表示您的总和。
首先,我是编程新手。 这对我来说只是一个简单有趣的项目,但我遇到了意想不到的问题,我不知道为什么。
背景:有点像《土拨鼠之日》,从一个月开始循环,到下一个循环时间减少一秒。我正在尝试计算总年数(通过计算总秒数)。 这是我的代码:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int loop=1;
double secondsInDay = 60*60*24; //86400
double secondsInMonth = 86400*30; //2592000
float secondsInLoop = 86400*30;
double totalYears = 0;
long totalSeconds = 0;
cout <<"Loop : "<<loop<<endl;
totalSeconds += secondsInLoop;
cout <<"-> Total seconds: "<<totalSeconds<<endl;
cout <<fixed<<setprecision(0)<<"-->Total time in this Loop: "<<secondsInLoop;
cout <<fixed<<setprecision(3)<<" seconds / "<<secondsInLoop/60<<" minutes / "<<secondsInLoop/3600<<" hours / "<<secondsInLoop/86400<<" days"<<endl<<endl;
while (secondsInLoop>0)
{
if (loop%1000==0)
{
cout <<"Loop: "<<loop<<endl;
cout <<"-> Total Seconds: "<<totalSeconds<<endl;
cout <<fixed<<setprecision(0)<<"-->Total time in this Loop: "<<secondsInLoop;
cout <<fixed<<setprecision(3)<<" seconds / "<<secondsInLoop/60<<" minutes / "<<secondsInLoop/3600<<" hours / "<<secondsInLoop/86400<<" days"<<endl;
totalYears = totalSeconds/(secondsInMonth*12); //31104000
cout <<fixed<<setprecision(3)<<"-->> Total Years: "<<totalYears<<endl<<endl;
}
totalSeconds = totalSeconds+secondsInLoop;
secondsInLoop--;
loop++;
}
cout <<"Loop: "<<loop<<endl;
cout <<"#-> Total Seconds: "<<totalSeconds<<endl;
totalYears = totalSeconds/(secondsInMonth*12); //31104000
cout <<"#->> Total Years: "<<totalYears<<endl<<endl;
return 0;
}
问题:在我的代码中,在大约循环 2461000 中,Total Seconds 被卡住了,不再增加。 奇怪的是,卡住的数字是3359234850816,距离long类型的最大数字还差得很远。 而且,如果我尝试正常计算(在另一个简单的算术代码中),就不会像那样卡住。
有人可以帮忙吗? 此外,我愿意接受任何关于整理它的建议,或任何与此相关的建议。谢谢
您已经超出了所选数字表示的限制。
这可能令人惊讶,因为大多数时候,当混合数字类型时,C++ 将转换为最能表示结果的类型。例如,将int
和long long
相加计算为long long
。添加一个float
和double
计算为一个double
。但是,您通过添加整数类型和 float
.
由usual arithmetic conversions,将任意整数类型和一个float
相加计算为一个float
。任何整数类型。如果您碰巧有一个 128 位 long long
和一个 32 位 float
,将它们相加会产生一个 32 位 float
。 float
被视为可以更好地表示数字,这是有好处的。典型的 32 位 float
确实具有与 128 位整数大致相同的 运行ge,具有能够表示非整数的好处。然而,虽然这种想法可能落后于规则,但规则只是 float
与整数类型组合产生 float
.
将此应用于更新 totalSeconds
.
totalSeconds = totalSeconds+secondsInLoop;
虽然 totalSeconds
是 long
,但 secondsInLoop
是 float
。这意味着当这些相加时,结果是 float
。据推测,这意味着一个 32 位值在有效数中有 24 个逻辑位(23 个实数位加上假定的 1)。这是结果的精度。仅保留总和的最高有效 24 位。当你的值停止增加时,整数是 3359234850816
而浮点值是 131071
(我 运行 你的代码想出这个)。这些值的比例是25629124
,一个25位的值。与totalSeconds
相比,secondsInLoop
的价值如此之小,就float
加法而言,还不如为零呢
要获得正确的计算,您需要更改结果的类型。最直接的方法是对所有整数值使用 long
,只记得在除法之前转换为浮点数。另一种方法是将 secondsInLoop
更改为 double
(就像您的其他保存整数的浮点变量一样 - 奇怪的是您选择了这个)。由于典型的 double
具有 53 位逻辑精度,因此它可以精确表示所有 32 位整数。因此,避免了这个问题(直到您需要转到 64 位整数...)。您还可以在总和中转换为整数类型,这会覆盖到浮点数的转换。
所以
long secondsInLoop = 86400*30;
或
double secondsInLoop = 86400*30;
或
totalSeconds = totalSeconds + static_cast<long>(secondsInLoop);
可以更精确地表示您的总和。