为什么(c ++)从long long unsigned int转换为long double和back会产生0

mmi*_*zwa 1 c++ casting biginteger

我有这样的程序:

#include "stdafx.h"
#include <iostream>

using namespace System;
using namespace std;

typedef long long unsigned int T_num;
typedef long double T_ld;


int main(array<System::String ^> ^args) {
    T_num a = numeric_limits<T_num>::max();
    T_ld b = numeric_limits<T_ld>::max();
    if ( b > a ) {
        cout << "decimal is bigger than integer" << endl;
    } else {
        cout << "integer is bigger than decimal" << endl;
    }
    T_num c;
    b = a;
    c = floor(b);
    if ( c == a) {
        cout << "OK" << endl;
    } else {
        cout << "dupa" << endl;
        cout << c << endl;
        cout << a << endl;
        cout << b << endl;
    }
    system("pause");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

哪个产生这样的输出:

decimal is bigger than integer
dupa
0
18446744073709551615
1.84467e+019
Press any key to continue . . .
Run Code Online (Sandbox Code Playgroud)

如果b可以包含a,那么为什么c为0?

嗯...它(网页)要求我提供更多细节,但我不确定我还能说什么...我希望如果适合b,那么它应该能够将它从b转换回c.

Mik*_*our 5

b不一定能包含a,只能近似它.long double具有比unsigned long long(因此更大的值max)更大的范围,但可能具有更少的尾数位来保持值的最高有效位,从而给较大值提供较低的精度.

最大值unsigned long long是位数2^N-1在哪里N; 可能是64.

如果long double具有少于N尾数位,那么转换将把它四舍五入到两个最接近的可表示值之一2^N.这超出了范围unsigned long long,因此转换回来会给出未定义的行为.也许它正在使用模运算减少到零(如果从整数类型转换会发生),但原则上任何事情都可能发生.

  • 好的,我确认了UB,"浮点类型的prvalue可以转换为整数类型的prvalue.如果截断的值无法在目标类型中表示,则行为是未定义的." 在[conv.fpint]中的C++11§4.9/ 1中. (2认同)