数据类型-浮点数
写在前面:
如果有幸能被你看到我的博客,那么很高兴能为你带来哪怕一点点的帮助,但需要说明的是,请你一定带着自己的想法去看任何教程和博客。
就如我而言,在编辑过程中,很有可能因为我的不小心或我自己知识理解的偏颇,亦或者是我看的资料有问题,从而在博客中呈现错误的信息。因此,希望你能客观看待,不盲从既有的资料。
最后,可以的话,点个赞吧~
一、从身高转换开始
在中国,我们基本上是使用公制单位居多,比如长度单位米m,质量单位千克kg等等。
在此背景下,我们来讨论一个问题:当使用英寸形容某人多高时,到底是说这个人多高呢?这就需要转换为我们熟悉的单位才有一个具体的概念,同样的例子还有摄氏温度和华氏温度的转换。
OK,fine,讨论下面一段代码:
#include <stdio.h>
int main()
{
printf("请分别输入身高的英尺和英寸,"
"如输入\"5 7\"表示5英尺7英寸:");
int foot;
int inch;
scanf("%f %f", &foot, &inch);
printf("身高是%f米。\n",
((foot + inch / 12) * 0.3048));
return 0;
}
其输出结果如下:
1.1 出错的代码
看上去结果似乎不错,但是再输入几组数据试试:
很明显的可以看到的是,好几组不同数据却得到了一样的结果,所以,显然这是错误的。
1.3 整数和浮点数
如果你愿意耗费时间去试试的话,你会发现任何两个十位数字相同的数据,得到的结果实际上都是一样的。
究其原因,在于C语言中,整数之间的运算只能得到整数,而10.0
和10
在C语言中是完全不同的两个数,前者是浮点数,而后者是整数(即int
类型)。这样一来,0-9中任意一个数字与12相除得到的商都是一个除去小数后的整数,很显然,这个整数为0。
因此,上述程序得到的结果实际上都只是foot
和0.3048
两者值的乘积而已。
1.2 10/3.03和10/33.0
再举一个小例子:
#include <stdio.h>
int main()
{
printf("%d\n", 10/3);
return 0;
}
上述例程得到的输出是
对的,就是3
,而非3.33333
的无限循环小数。另外,我们还可以再来一点改变以验证其正确性:
#include <stdio.h>
int main()
{
printf("%d\n", 10/3*3); # 在除以3之后再乘以3
return 0;
}
输出如下:
一个数对另一个非零数进行先除后乘的操作,其值本应保持不变,但是从上面图片中可以得到的是,10
变成了9
。
如果将10
该改成10.0
呢?
#include <stdio.h>
int main()
{
printf("%d\n", 10.0/3);
return 0;
}
输出如下:
可以看到的是,输出并没有变化,依然是3,这是因为前面的格式化字符串中的%d
规定了输出为int
类型,在完成运算后,printf
将其打印出来的时候,格式化字符串将浮点型的计算结果“降级”为整形,从而输出为3
。
可以改变格式化字符串看看结果是否会变化:
#include <stdio.h>
int main()
{
printf("%f\n", 10.0/3);
return 0;
}
输出结果如下,结论正确。
值得一提的是,整型和浮点型虽然可以互相转换,但是可能会造成精度损失的结果。
在C语言中,整型到浮点型的转换一般是直接在原数据后面加小数点和零来实现,而浮点型到整型的转换则是抹除原数据后面的小数点和零。在此过程中,整型到浮点型还好,没啥大问题,而浮点型到整型的转换则可能会因为小数部分的去除造成部分数据丢失,从而损失精度,比如从1.8变成了1,这是编程时应该注意的问题。
将格式化字符串更改后,再进行之前的对同一个数先除后乘的实验:
#include <stdio.h>
int main()
{
printf("%f\n",10.0/3*3);
return 0;
}
结果证实结论,欧克,搞定。
实际上,除了浮点数以外,还有一个叫定点数的东西,其小数点的位置是固定的,在C语言中,你不会遇到定点数,人们借用“浮点数”来表达所有的带小数点的数。
1.4 正确的写法
将身高转换程度修改如下:
#include <stdio.h>
int main()
{
printf("请分别输入身高的英尺和英寸,"
"如输入\"5 7\"表示5英尺7英寸:");
int foot;
int inch;
scanf("%d %d", &foot, &inch);
printf("身高是%f米。\n",
((foot + inch / 12.0) * 0.3048));
return 0;
}
由此得出的输出就是完全正确的。
另外一种修改方式就是改变foot
和inch
的变量类型。
在之前的运算中,我们将12改成了12.0,其目的在于使inch
作为浮点型参与运算,从而使输出不损失精度。针对于此,我们只要修改inch
的变量类型即可。
inch
是定义为int
类型的变量,如果把int
换成double
,我们就把它改为double
类型的浮点型变量了。
double(双倍的,两个的,成双的),它本来是双精度浮点数的第一个单词,人们用来表示浮点书类型。除double
以外,还有float
(漂浮,浮动)表示单精度浮点数。
修改后的代码如下:
#include <stdio.h>
int main()
{
printf("请分别输入身高的英尺和英寸,如输入\"5 7\"表示5尺七英寸:");
double foot, inch;
scanf("%lf %lf", &foot, &inch);
printf("身高是:%f米。\n", ((foot + inch / 12) * 0.3048));
return 0;
}
输入如下所示:
user@user-LM-LS3A4000-7A1000-1w-V01-pc-A2005:~/桌面$ ./a.out
请分别输入身高的英尺和英寸,如输入"5 7"表示5尺七英寸:5 7
身高是:1.701800米。
user@user-LM-LS3A4000-7A1000-1w-V01-pc-A2005:~/桌面$ ./a.out
请分别输入身高的英尺和英寸,如输入"5 7"表示5尺七英寸:5 6
身高是:1.676400米。
- 当定义变量为
double
类型时,就不再需要将12
改为12.0
,直接带入运算即可; - 另外,当变量被定义为
double
类型,函数scanf
的参数(格式化字符串中的参数)也应该发生变化,即由原来的%d
换成%lf
,不应该忘记的是,scanf
中的foot
等变量之前应该加上&
。
1.5 已知整理
到目前为止,已知C语言的数据类型有:
- 整数
- int定义
- print("%d”, …)输出
- scanf("%d",…)输入
- 带小数点的数(浮点数)
- double 定义
- printf("%f",&…)输出
- scanf("%lf",&…)输入
表达式
二、关于表达式
2.1 定义
表达式是一系列运算符和算子的组合,用来计算一个值。
下面列举一些:
amount=x * (1 + 0.033) * (1 + 0.033) * (1 + 0.033);
tottal = 27;
count = count + 1;
value = (min / 2) * lastValue;
······
定义中,有那么几个概念需要了解:
- 运算符(operator),指进行运算的动作,比如加法运算符“+”,减法运算符“-”;
- 算子(operand),指参与运算的值,这个值可能是常数,也可能是变量,还可能是一个方法的返回值。
例如,在表达式a = b + 5
中,算子为:a
、b
、5
,运算符为=
、+
。
讲到这里,需要回忆一下之前提到的的C语言中的运算:
四则运算 | C语言符号 | 意义 |
---|---|---|
+ | + | 加 |
- | - | 减 |
× | * | 乘 |
÷ | / | 除以 |
% | 取余 | |
() | () | 括号 |
假设我们现在要写一个程序,目的是计算两个时间点之间的时间差,时间点以小时和分钟为单位,输出为两个时间点之前的差,同样也以几小时几分表示。
当写一个程序时,需要思考两件事:
第一,做这件事,我们需要得到怎样的数据,然后怎么保存它