类型铸造长双至长长

时间:2019-05-04 21:51:42

标签: c types

我正在按照C语言进行类型转换

long double dec = 12.32;
long double n = dec - (long long)dec;

当我在点“之后”打印n的6位数字时。假设n为0.32,则得出3、1、9、9、9、9; 但是当我这样做时

double n = dec - (int)dec;

打印正确(3、2、0、0、0、0),我不知道为什么

打印代码仅为:

for (int i = 0; i < 6; i++)
{
   n *= 10;
   printf("%d digit = %d or %lld\n", i, (int) or (long long)n);
   n -= (int) or (long long)n;
}

2 个答案:

答案 0 :(得分:3)

12.32无法用您的C实现用于long doubledouble的格式表示。

long double中最接近12.32的可表示值可以是12.319999999999999999722444243843710864894092082977294921875。这部分可以解释您的程序为何显示3、1、9、9、9和9(这些是数字的实际十进制数字)的原因。

类似地,double中最接近12.32的可表示值可能是12.32000000000000028421709430404007434844970703125,这将解释您的程序为何显示3、2、0、0、0和0的原因。

但是,在您显示的代码中,long double dec = 12.32;12.32是一个double常量。即使您将其分配给double,它也应具有long double值。因此,这不能解释您的程序为何显示3、1、9、9、9和9的原因。您需要使用l后缀使其成为long double常量,如long double dec = 12.32l; 。可能您在问题中显示的代码与您用来生成3、1、9、9、9和9的代码不完全相同。

此外,不能依靠代码n *= 10;来提取数字。这是因为通常,将doublelong double值乘以10的数学结果无法以doublelong double格式表示-因为10需要三个有效位代表(101 2 •2 1 )位,确切乘积可能比double中需要更多有效位。因此,精确的数学结果将四舍五入以适合浮点格式。换句话说,n *= 10;会更改值;它不仅会乘以10。因此,它不会总是产生原始数字的数字。

答案 1 :(得分:-2)

工作正常。但是您的代码有很多问题:

for (int i = 0; i++; i < 6)不符合您的想法:)(请参见我的回答)

printf long long要求%lld,如果您使用%d,则是未定义的行为

void foo(long double dec)
{
    long double n = dec - (long long)dec;

    for (int i = 0; i< 6; i++)
    {
        n *= 10;
        printf("%d digit = %lld\n", i, (long long)n);
        n -= (long long)n;
    }

    printf("%lld\n", (long long)(n * 100)); 
}

int main()
{
    foo(12.32);

    return 0;
}

https://ideone.com/DGvPQJ

编辑

您的编译器似乎不使用浮点数而不是double或long double的