double __int64

首先先讲下:float与double类型的内存分布,精度和范围

 

内存分布:

C/c++的浮点数据类型有float和double两种。

float大小为4字节,内存中的存储方式如下:
符号位(1bit)指数(8bit)尾数(23bit)
double大小为8字节,内存中的存储方式如下:
符号位(1bit)指数(11bit)尾数(52bit)

符号位决定浮点数的正负,0正1负。
指数和尾数均从浮点数的二进制科学计数形式中获取。

如,十进制浮点数2.5的二进制形式为10.1,转换为科学计数法形式为(1.01)*(10^1)。
由此可知指数为1,尾数(即科学计数法的小数部分)为01。
根据浮点数的存储标准,指数用移码表示。0的float类型移码为127(0111 1111),0的double类型移码为1023(011 1111 1111)。运算时,在0的移码基础上加指数,得到的就是内存中指数的表示形式。尾数则直接填入,如果空间多余则以0补齐,如果空间不够则0舍1入。所以float和double类型分别表示的2.5如下(二进制):
符号位 指数  尾数
0 1000 0000 010 0000 0000 0000 0000 0000
0 100 0000 0000 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

精度:
float和double的精度是由尾数的位数来决定的。
float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字;
double:2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位。

范围:
float类的指数是8位移码,最大为127最小为-127,127用来作2的指数,为2^127,约等于 1.7014*10^38, 而我们知道,floa示数范围约为-3.4*10^38-------3.4*10^38, 这是因为尾数都为1时,即1.11..11约为2,因此浮点数的范围就出来了.double的情况与float完全相似.
接下来切入主题:

我们先看下这道题目,http://acm.pku.edu.cn/JudgeOnline/problem?id=1306

这道题目的大概意思就是求排列组合,先把代码贴出来:

#include<stdio.h>
int main()
{
 int i,N,M;
 double Sum;
 while (scanf("%d %d",&N,&M)!=-1&&N&&M)
     {
     Sum=1;
      for(i=1;i<=M;i++)
        {
         Sum*=(N-i+1);
         Sum/=i;            
        }
      printf("%d things taken %d at a time is %.0lf exactly./n",N,M,Sum);
     }
     return 0;
}

然后我们在看下这道题目:

http://acm.hdu.edu.cn/showproblem.php?pid=1002

我们用相同的方法试下,代码如下:

#include<stdio.h>
int main()
{
 int T,i;
 double a,b;
 while(scanf("%d ",&T)!=-1)
     {
      for(i=1;i<=T;i++)
        {
         scanf("%lf %lf",&a,&b);
         printf("Case %d:/n",i);
         printf("%.0lf + %.0lf= %.0lf/n/n",a,b,a+b);             
        }           
     } 
}

当我们输入112233445566778899 998877665544332211时,打印出如下
Case 1:
112233445566778900 + 998877665544332160= 1111111111111111000

咦,怎么搞的,怎么超出了,double的范围不是很大吗,怎么超出了呢?

上面的题目怎么没有超出呢?

原因是这样的,我们直接赋值会溢出,但第一题就不会溢出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是计算用时的函数实现: ``` double duration(int s_hour, int s_min, double s_sec, int e_hour, int e_min, double e_sec) { double start_time = s_hour * 3600 + s_min * 60 + s_sec; double end_time = e_hour * 3600 + e_min * 60 + e_sec; return end_time - start_time; } ``` 该函数接受起始时间和结束时间的小时、分钟和秒,将其转换为以秒为单位的总时间,并返回用时,即结束时间减去起始时间。 ### 回答2: 函数实现代码如下: ```python def duration(s_hour, s_min, s_sec, e_hour, e_min, e_sec): # 将起始时间换算为秒 start_time = s_hour * 3600 + s_min * 60 + s_sec # 将结束时间换算为秒 end_time = e_hour * 3600 + e_min * 60 + e_sec # 计算用时(单位为秒) elapsed_time = end_time - start_time # 将秒转换为小时、分钟、秒 elapsed_hour = int(elapsed_time / 3600) elapsed_minute = int((elapsed_time % 3600) / 60) elapsed_sec = elapsed_time % 60 # 返回用时 return elapsed_hour, elapsed_minute, elapsed_sec ``` 解释:首先将起始时间和结束时间分别换算成秒,然后计算用时(结束时间减去起始时间),再将用时换算为小时、分钟、秒,并返回结果。需要注意的是,这里函数返回的是一个包含小时、分钟、秒的元组。 ### 回答3: 函数的输入参数是起始时间和结束时间,分别由起始小时数(s_hour)、起始分钟数(s_min)、起始秒数(s_sec)、结束小时数(e_hour)、结束分钟数(e_min)和结束秒数(e_sec)组成。 函数需要返回时间的用时,用一个浮点数表示。 首先,我们可以将起始时间和结束时间的小时、分钟和秒数转换为总秒数,方便后续计算。具体转换方式如下: 起始总秒数 = s_hour * 3600 + s_min * 60 + s_sec 结束总秒数 = e_hour * 3600 + e_min * 60 + e_sec 计算用时的总秒数,只需将结束总秒数减去起始总秒数,即: 用时总秒数 = 结束总秒数 - 起始总秒数 最后,将用时总秒数转换为小时部分、分钟部分和秒部分。小时部分可以通过用时总秒数整除3600得到,分钟部分可以通过用时总秒数除以60取模得到,秒部分可以通过用时总秒数除以60取余得到。 具体代码实现如下: ```cpp double duration(int s_hour, int s_min, double s_sec, int e_hour, int e_min, double e_sec) { double s_total_sec = s_hour * 3600 + s_min * 60 + s_sec; double e_total_sec = e_hour * 3600 + e_min * 60 + e_sec; double total_duration_sec = e_total_sec - s_total_sec; int duration_hour = total_duration_sec / 3600; int duration_min = (int)(total_duration_sec / 60) % 60; double duration_sec = total_duration_sec - duration_hour * 3600 - duration_min * 60; return duration_hour + duration_min / 60.0 + duration_sec / 3600.0; } ``` 这样,调用duration函数,将起始时间和结束时间作为参数传入,即可返回时间的用时。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值