a905448839 发表于 2023-4-13 21:43:08

经典C程序第三题(求助)

x 和 y是int类型,在整个程序中也一直是int类型。但是调用sqrt返回的是double类型,为什么没有把x或y强制转换成double类型呢?我印象中 长类型给短类型赋值好像自动强制转换的呢?求大佬详细展开说说。
#include<stdio.h>
#include <math.h>
int main()
{
    long int i, x, y;
   
    for (i=1;i<100000;i++)
    {
      x = sqrt(i+100); /*x为加上100后开方后的结果*/
      y = sqrt(i+268); /*y为再加上168后开方后的结果*/
      if(x*x==i+100&&y*y==i+268)
      {
            printf("\n%ld\n",i);/*如果一个数的平方根的平方等于该数,这说明此数是完全平方数*/
      }
    }

    return 0;
}

isdkz 发表于 2023-4-13 21:46:54

在这段代码中,sqrt() 函数的返回类型确实是 double,但实际上你并没有强制转换 x 或 y 为 double 类型。x 和 y 被赋予了 sqrt() 函数返回的 double 类型值,但这里发生了隐式类型转换,即将 double 类型转换为 long int 类型。这种转换可能会导致精度损失。

当一个表达式中出现了不同类型的操作数时,编译器会自动将较短类型的操作数转换为较长类型的操作数,以确保计算结果的正确性。这个过程叫做类型提升。在这里,sqrt() 函数返回的是 double 类型,而 x 和 y 是 long int 类型,所以发生了隐式类型转换,将 double 类型转换为 long int 类型。

你提到的长类型给短类型赋值时的自动强制转换其实就是这个隐式类型转换的过程。在这种情况下,编译器可能会发出警告,因为这种转换可能会导致精度损失。

如果你想避免隐式类型转换,可以显式地进行类型转换。例如,你可以使用强制类型转换 (C-style cast) 或者 C++ 风格的类型转换 (如 static_cast<double>(x) ) 来将 x 或 y 转换为 double 类型。然后,你可以将转换后的 double 类型值与其他 double 类型值进行运算,以确保计算结果的正确性。

a905448839 发表于 2023-4-13 22:09:39

本帖最后由 a905448839 于 2023-4-13 22:18 编辑

isdkz 发表于 2023-4-13 21:46
在这段代码中,sqrt() 函数的返回类型确实是 double,但实际上你并没有隐形转换 x 或 y 为 double 类型。x...

你的意思是long int类型 和double类型相比 long int类型更长?
那如果如下 我定义为int类型的x y sqrt函数返回的double类型但是x y还是int类型 并没隐形转换(int 类型比double类型短)

#include<stdio.h>
#include <math.h>
int main()
{
    int i, x, y, z;
    for (i=1;i<100000;i++)
    {
      x = sqrt(i+100); /*x为加上100后开方后的结果*/
      y = sqrt(i+268); /*y为再加上168后开方后的结果*/
      if(x*x==i+100&&y*y==i+268)
      {
            printf("\n%ld\n",i);/*如果一个数的平方根的平方等于该数,这说明此数是完全平方数*/
      }
    }

    return 0;
}

isdkz 发表于 2023-4-13 22:17:31

a905448839 发表于 2023-4-13 22:09
你的意思是long int类型 和double类型相比 long int类型更长?
那如果如下 我定义为int类型的x y sqrt函 ...

不是呀,就是 double 类型更长,所以转成 long int 才会精度丢失呀,你用 int 也是一样的

在 C 语言中,double 类型的长度(所占用的字节数)通常比 int 和 long int 都要大。这里的“长度”指的是数据类型所占用的字节数。因此,double 类型的长度比 int 类型的长度要长。

在你提供的代码中,x 和 y 的类型为 int,而 sqrt() 函数的返回类型为 double。当将 sqrt() 函数的返回值赋给 x 和 y 时,会发生隐式类型转换,将 double 类型转换为 int 类型。这种转换可能导致精度损失。在这里,虽然没有显式地进行强制类型转换,但编译器已经隐式地将 double 类型转换为 int 类型。这种情况下,编译器可能会发出警告,提醒你可能发生精度损失。

在你的示例代码中,x 和 y 仍然是 int 类型,虽然 sqrt() 函数返回的是 double 类型。在这种情况下,由于 double 类型到 int 类型的隐式类型转换,可能导致精度损失。如果想避免这种情况,可以考虑将 x 和 y 的类型定义为 double 类型,或者显式地进行类型转换。

a905448839 发表于 2023-4-13 22:26:06

isdkz 发表于 2023-4-13 22:17
不是呀,就是 double 类型更长,所以转成 long int 才会精度丢失呀,你用 int 也是一样的

在 C 语言中 ...

好的,我大概理解了
如果我不强制转换x和y的类型类型就不会发生转换?x y始终都是int类型?
如果我 (double)x = sqrt(i+100);或对y这样操作 x和y的值才会被强制转换成double类型
但是我在我学习C语言课程中 好像有一个地方是好像程序会自动给我强制转换 就算我不给他(double)x这样去编写,他也会强制转换,我忘记了是不是赋值运算会这样还是在哪种情况下会这样,你知道吗?如果有,请告诉我!谢谢

isdkz 发表于 2023-4-13 22:29:59

a905448839 发表于 2023-4-13 22:26
好的,我大概理解了
如果我不强制转换x和y的类型类型就不会发生转换?x y始终都是int类型?
如果我 ( ...

即使你不强制转换,当你试图把他赋给另一个类型的时候,他也会隐式转换的

你不用 (double) 这种方式不叫强制转换,而是叫隐式转换

a905448839 发表于 2023-4-13 22:39:13

isdkz 发表于 2023-4-13 22:29
即使你不强制转换,当你试图把他赋给另一个类型的时候,他也会隐式转换的

你不用 (double) 这种方式不 ...

可是隐时转换也没有发生啊 x和y一直是int类型 把sqrt返回的double类型给他 他依然是int类型并没有发生任何转换啊

isdkz 发表于 2023-4-13 22:41:55

a905448839 发表于 2023-4-13 22:39
可是隐时转换也没有发生啊 x和y一直是int类型 把sqrt返回的double类型给他 他依然是int类型并没有发生 ...

sqrt的返回值本来是 double 类型的,赋给 x 和 y 之后成了 int 类型,这可不就从 double 类型转成 int 类型了么

你不要把 x 和 y 跟 sqrt 的返回值搞混了,sqrt的返回值本来是不属于 x 和 y 的

a905448839 发表于 2023-4-13 22:44:38

isdkz 发表于 2023-4-13 22:41
sqrt的返回值本来是 double 类型的,赋给 x 和 y 之后成了 int 类型,这可不就从 double 类型转成 int 类 ...

我明白了是把sqrt返回值的double类型 转换成int类型 给了 x和y 是这样吗?

isdkz 发表于 2023-4-13 22:46:33

a905448839 发表于 2023-4-13 22:44
我明白了是把sqrt返回值的double类型 转换成int类型 给了 x和y 是这样吗?

对呀,本来 x 和 y 的容量就小,大的肯定是转小了才装得下呀

a905448839 发表于 2023-4-13 22:50:36

isdkz 发表于 2023-4-13 22:46
对呀,本来 x 和 y 的容量就小,大的肯定是转小了才装得下呀

那么隐式转换就不会存在什么要存放的地方(xy)小了我把它(x y)转大
而是把要转的地方(sqrt的返回值)变小吗?
页: [1]
查看完整版本: 经典C程序第三题(求助)