pi的倍数到千分之一的值可能会改变循环执行方式

Do multiples of Pi to the thousandths have a value that may change how a loop executes?

本文关键字:改变 循环 执行 方式 千分之一 pi      更新时间:2023-10-16

最近我决定进入C ,经过基础知识后,我决定仅使用iostream构建计算器(只是为了挑战自己)。大部分完成后,我遇到了指数的循环问题。每当将PI的倍数用作指数时,它都会循环多次。我以一种多余的方式修复了它,现在我希望有人能够告诉我发生了什么。我的未修复代码片段在下面。忽略上面的所有内容,而只是查看功能齐全的代码的最后一点。我所想的是为什么Pi的值会如此之多。谢谢。

bool TestForDecimal(double Num) /* Checks if the number given is whole or not */ { 
    if (Num > -INT_MAX && Num < INT_MAX && Num == (int)Num) {
        return 0;
    }
    else {
        return 1;
    }
}

,然后所有出错的地方(分母设置为1)

if (TestForDecimal(Power) == 1) /* Checks if its decimal or not */ {
    while (TestForDecimal(Power) == 1) {
        Power = Power * 10;
        Denominator = Denominator * 10;
    }
}

如果有人可以给我一个很好的解释!

进一步澄清,即使在电源成为整个数字之后,while循环仍在循环(仅当电源等于PI的倍数(例如3.1415或6.2830)等)

) )

您可以尝试的完整代码:

#include <iostream>
bool TestForDecimal(double Num) /* Checks if the number given is whole or not */ {
if (Num > -INT_MAX && Num < INT_MAX && Num == (int)Num) {
    return 0;
}
else {
    return 1;
}
}
void foo(double Power) {
double x = Power;
if (TestForDecimal(x) == 1) /* Checks if its decimal or not */ {
    while (TestForDecimal(x) == 1) {
        x = x * 10;
        std::cout << x << std::endl; 
    }
}
}
int main() {
foo(3.145); // Substitute this with 3.1415 and it doesn't work (this was my problem)
system("Pause");
return 0;
}

做这样的事情有什么问题?

#include <cmath> // abs and round
#include <cfloat> // DBL_EPSILON
bool TestForDecimal(double Num) {
  double diff = abs(round(Num) - Num);
  // true if not a whole number
  return diff > DBL_EPSILON;
}

外观效率很低...如果num很大...

更快的方法可能是

if (Num == static_cast<int>(Num))

 if (Num == (int)Num)

如果您喜欢C风格语法。

然后,范围检查可能很有用... OE是在大于2^32(约40亿)

时询问num是否为intger是没有意义的。

最终不认为这些数字是小数。它们被存储为二进制数字,而不是将功率和分母乘以2,而是将它们乘以2。

大多数十进制分数不能完全以二进制浮点格式表示,因此您要做的事情一般无法使用。例如,使用标准的64位double格式,最接近3.1415的代表值更像3.1415000000000001812

如果您需要准确表示十进制分数,则需要一种非标准类型。BOOST.MULTIPRECISION具有一些小数类型,并且有一个建议在标准库中添加小数类型。某些实现可能对此具有实验支持。

当心。double IS(通常我认为您使用标准架构)以IEE-754格式表示,即 Mantissa * 2 exponent 。对于双重,您有53位用于Mantissa零件,一个用于符号,指数为10位。当您将其乘以10时,它将增长,并且一旦指数大于53。

不幸的是,除非您有一个64位系统,否则不能将53位整数表示为32位int,并且您的测试将再次失败。

因此,如果您有一个32位系统,则永远不会达到整数值。您更有可能达到无限代表并留在那里...

唯一可以使用的用例是,如果您以少量负功率为2表示的数字,例如0.5(1/2),0.25(1/4),0.75(1/2 1/4),几乎所有的曼蒂萨部分数字为0。

研究了"未修复"功能后,据我所知,这是您的基本算法:

  1. double TestForDecimal(double Num) { ...

接受double并返回double的功能。如果返回值是小数值,这是有道理的,但是由于事实并非如此,也许您是要使用bool

  1. while (Num > 1) { make it less }

虽然这没有任何本质上的错误,但它并没有真正以较大的幅度来解决负面数字,因此您会遇到问题。

  1. if (Num > -INT_MAX && Num < INT_MAX && Num == (int)Num) { return 0; }

这意味着,如果Num在签名的整数范围内,并且其整数类型等于自身,请返回将0返回到double。这意味着您不在乎整数范围以外的数字是否为全数字。要解决此问题,请将条件更改为if (Num == (long)Num),因为sizeof(long) == sizeof(double)

也许您刚刚解释的算法您的功能可能会阐明您的问题。