我正在按照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;
}
答案 0 :(得分:3)
12.32无法用您的C实现用于long double
或double
的格式表示。
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;
来提取数字。这是因为通常,将double
或long double
值乘以10的数学结果无法以double
或long 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;
}
您的编译器似乎不使用浮点数而不是double或long double的