为什么这两个代码片段会产生不同的结果? (浮点数、双精度)

发布于 2024-12-28 15:36:34 字数 945 浏览 4 评论 0原文

我才刚刚开始学习 C++,并且一直在处理 float 和 double 值。下面是两个代码片段,在我看来,它们在做同样的事情,但给出了不同的结果。我缺少什么?有人可以解释一下精度错误吗?第一个代码必须得到与第二个代码不同的结果。

int _tmain(int argc, _TCHAR* argv[])
{
    const float f = 0.1;
    const double d = 0.1;
    int counter = 0;

    for(counter; ((double)counter * f - (double)counter * d) < 0.34; counter++) {}

    cout << "Iterations = " << counter << "\n" ;

    system("pause");
    return 0;
}


int main (int argc, const char * argv[])
{
    float time_f = 0.1;    
    double time_d = 0.1;
    float total_f = 0;
    double total_d = 0;
    int count=0;
    double difference = 0;
    while (true) {
        total_d = count * time_d;
        total_f = count * time_f;
        if(total_f - total_d >= 0.34){

            break;
        }
        count++;

    }
    std::cout <<  count << "\n";
    system("pause");
}

我已经改变了 float 和 double 之间的 for 循环条件的转换,但值没有不同。

I am only beginning to learn C++ and have been messing around with float and double values. Below are two code snippets that seem to me to be doing the same thing but give different results. What am I missing? Can someone explain the precision error the first code must have to get a different result than the second.

int _tmain(int argc, _TCHAR* argv[])
{
    const float f = 0.1;
    const double d = 0.1;
    int counter = 0;

    for(counter; ((double)counter * f - (double)counter * d) < 0.34; counter++) {}

    cout << "Iterations = " << counter << "\n" ;

    system("pause");
    return 0;
}


int main (int argc, const char * argv[])
{
    float time_f = 0.1;    
    double time_d = 0.1;
    float total_f = 0;
    double total_d = 0;
    int count=0;
    double difference = 0;
    while (true) {
        total_d = count * time_d;
        total_f = count * time_f;
        if(total_f - total_d >= 0.34){

            break;
        }
        count++;

    }
    std::cout <<  count << "\n";
    system("pause");
}

I have altered the cast of my for loop condition between float and double but the value does not differ.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

关于从前 2025-01-04 15:36:35

这两个代码片段之间的区别在于强制转换。 counter * f 在第一个代码段中被转换为 double 并在第二个代码段中存储为 float 变量。

下面是它的外观示例:

#include <stdio.h>

int main(int argc, char* argv[])
{
    const float f = 0.1;
    const double d = 0.1;
    int count = 0;

    for(count; (double)(count * f) - (double)(count * d) < 0.34; count++);

    printf("Iterations = %d\n", count);
    count = 0;

    while (true)
    {
        double total_d = count * d; // is equal to (double)(count * d)
        double total_f = count * f; // is equal to (double)(count * f)
        if (total_f - total_d >= 0.34)
            break;
        count++;
    }
    printf("Iterations = %d\n", count);

    return 0;
}

Difference between that two code snippets is in cast. counter * f is casted to double in first snippet and stored to float variable in second one.

Here's an example of how it could look like:

#include <stdio.h>

int main(int argc, char* argv[])
{
    const float f = 0.1;
    const double d = 0.1;
    int count = 0;

    for(count; (double)(count * f) - (double)(count * d) < 0.34; count++);

    printf("Iterations = %d\n", count);
    count = 0;

    while (true)
    {
        double total_d = count * d; // is equal to (double)(count * d)
        double total_f = count * f; // is equal to (double)(count * f)
        if (total_f - total_d >= 0.34)
            break;
        count++;
    }
    printf("Iterations = %d\n", count);

    return 0;
}
放赐 2025-01-04 15:36:35

您还没有在这里将 count 转换为 double:

total_d = count * time_d;
total_f = count * time_f;

另一件事,这些循环永远不会结束,因为两个减法操作数具有相同的值:S

You haven't casted count to double here:

total_d = count * time_d;
total_f = count * time_f;

Another thing, those loops will never end since both subtraction operands have the same value :S

好多鱼好多余 2025-01-04 15:36:34

floatdouble 都有有限表示,这意味着它们
呈现一系列离散值,而不仅仅是任何实际值。在
特别是,在您的示例中, 0.1 没有精确的浮点
我所知道的任何现代机器上的表示(所有这些机器都使用一个基础
在其实现中是 2 的幂 -0.11/5 *
1/2
,任何 1/5 的倍数都不可能有有限的
表示,除非底数是 5 的倍数)。

结果是 floatdouble 具有相同的底层
表示(通常情况并非如此),否则会有差异
一旦 count 不同于 0。

这个主题的通常参考是
“什么
每个计算机科学家都应该了解浮点
算术”。直到您阅读并理解(或至少
理解其含义)它,你不应该触摸浮动的机器
观点。

Both float and double have a finite representation, which means they
take on a series of descrete values, and not just any real value. In
particular, in your example, 0.1 has no exact floating point
representation on any modern machine I know of (all of which use a base
which is a power of 2 in their implementation—0.1 is 1/5 *
1/2
, and nothing which is a multiple of 1/5 can have a finite
representation unless the base is a multiple of 5).

The result is that either float and double have the same underlying
representation (not usually the case), or there will be a difference as
soon as count is different from 0.

The usual reference for this subject is
“What
Every Computer Scientist Should Know About Floating-Point
Arithmetic”. Until you've read and understood (or at least
understood the implications) it, you shouldn't touch machine floating
point.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文