首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >长int与双倍在c++中表达评价的差异

长int与双倍在c++中表达评价的差异
EN

Stack Overflow用户
提问于 2022-01-13 06:38:20
回答 2查看 91关注 0票数 1

我将参考下面的代码来解释我的问题。

代码语言:javascript
复制
typedef long long int ll;

void func(){
    ll lli_a = 603828039791327040;
    ll lli_b = 121645100408832000;
    double d_b = (double)lli_b;
    cout << "a " << lli_b - d_b << endl; \\0
    cout << "b " << (lli_a - 4*lli_b) - (lli_a - 4*d_b) << endl; \\64
    cout << "c " << (lli_a - 4*lli_b) - (lli_a - (ll)4*d_b) << endl; \\64
    cout << "d " << (lli_a - 4*lli_b) - (lli_a - 4*(ll)d_b) << endl; \\0
    cout << "e " << 4*(ll)d_b - 4*d_b << endl; \\0
    cout << "f " << 4*(ll)d_b - (ll)4*d_b << endl; \\0
}

我无法理解为什么语句b和c计算为64,而d计算为0,这恰好是正确的答案。

E和f的计算值都为0,因此,由于从lli_a中减去,所以差别就出现了。我不认为存在任何溢出问题,因为每个术语的单个值都是正确的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-13 07:09:26

一些代码可以让您通过它,底线不混入双倍与ints隐式

代码语言:javascript
复制
#include <cassert>
#include <iostream>
#include <type_traits>

// typedef long long int ll; NO , use using and never use aliasing to safe a bit of typing. Aliases are there to introduce meaning not shortcuts

//using namespace std; // also NO

int main() 
{
    long long int lli_a = 603828039791327040;
    long long int lli_b = 121645100408832000;
    //double d_b = (double)lli_b;                     // No this is C++ don't use 'C' style casts
    double d_b = static_cast<double>(lli_b);

    assert(static_cast<long long int>(d_b) == lli_b); // you are in luck the double can represent your value exectly, NOT guaranteed

    std::cout << "a " << lli_b - d_b << "\n"; //  endl; \\0 don't use endl unless you have a good reason to flush

    long long int lli_b4 = 4 * lli_b;
    
    // use auto to show you this expression evaluates to a double!
    auto lli_d_b4 = (lli_a - static_cast<long long int>(4) * d_b); // d_b is double!!! what do you want to do here? Use it as a long long int then cast it first
    static_assert(std::is_same_v<double, decltype(lli_d_b4)>);

    auto result_c = lli_b4 - lli_d_b4;
    // result c is still a double!
    static_assert(std::is_same_v<double, decltype(result_c)>);
    std::cout << "c " << result_c << "\n";
    
    // long story short don't mix types implicitly and use "C++" style cast explicitly to get the results you want

    /*

    
        cout << "b " << (lli_a - 4 * lli_b) - (lli_a - 4 * d_b) << endl; \\64
        cout << "c " << (lli_a - 4 * lli_b) - (lli_a - (ll)4 * d_b) << endl; \\64
        cout << "d " << (lli_a - 4 * lli_b) - (lli_a - 4 * (ll)d_b) << endl; \\0
        cout << "e " << 4 * (ll)d_b - 4 * d_b << endl; \\0
        cout << "f " << 4 * (ll)d_b - (ll)4 * d_b << endl; \\0
        */

    return 0;
}
票数 0
EN

Stack Overflow用户

发布于 2022-01-13 06:47:50

double是浮点类型。浮点类型的精度有限。它们不能代表所有的数字,甚至不代表所有的有理数。简单地(在您的系统上) 603828039791327040是一个不能用double数据类型表示的数字。可表示的最接近的值恰好与精确值相距64。

您可以(很可能)通过使用long double (通常)表示long long的所有值来获得预期的结果--或者首先可以避免使用浮点数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70692366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档