免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7466 | 回复: 11
打印 上一主题 下一主题

[其他] 很简单很简单的题 帮忙看看。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-07-27 17:52 |只看该作者 |倒序浏览
#include<stdio.h>
#include<math.h>

int main()
{
    int n;
    __int64 k;
    while(scanf("%d",&n)!=EOF)
    {
        k=pow(3,n)-1;
        printf("%I64d\n",k);
    }
    return 0;
}

主要是求n^3-1的结果,但是当我输入35时结果为50031545098999705,但是我用计算器算出来是50031545098999706.。。这是为什么呢?
而且输入36时又是真确的。    想了半天不知道所以到这里来问问。    先谢谢大神。回答。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2013-07-27 21:17 |只看该作者
pow返回值是double,double不是精确的

论坛徽章:
0
3 [报告]
发表于 2013-07-27 23:55 |只看该作者
回复 2# hellioncu


    哦  那这是为什么啊  。math.h里的pow函数是什么样子的啊?

论坛徽章:
0
4 [报告]
发表于 2013-07-28 18:08 |只看该作者
double pow(double x, double y);

论坛徽章:
0
5 [报告]
发表于 2013-07-29 00:02 |只看该作者
回复 4# haoyuejushi

这我知道   在math中的原代码??

   

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
6 [报告]
发表于 2013-07-29 08:47 |只看该作者
reborn_wwp 发表于 2013-07-29 00:02
回复 4# haoyuejushi
这我知道   在math中的原代码??


要源代码干球呀?
3^35 = 50031545098999707
log2(50031545098999707) = 55.47
也就是起码要56bits才能完整表达3^35的结果
而double的尾数才52Bits(即使算上隐含位才53bits),因此从理论上讲double是肯定无法完整表达3^35的。
用你的那个__int64(为什么不用unsigned long long?)将3乘它35次吧,或者用快速幂算法。

“而且输入36时又是真确的。” ------ 只是碰巧吧,你试试下面这段代码,肯定输出一样,即必然有一个pow(3.0,36.0)是不完整的
  1. __int64 a = pow(3.0,36.0) - 1;
  2. printf( "%I64d\n", a );
  3. __int64 b = pow(3.0,36.0);
  4. printf( "%I64d\n", b );
复制代码

论坛徽章:
0
7 [报告]
发表于 2013-07-30 15:58 |只看该作者
回复 6# bruceteen


    谢谢了啊

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
8 [报告]
发表于 2013-07-30 16:22 |只看该作者
随手写个快速幂算法
  1. #include <stdio.h>

  2. unsigned long long pown( unsigned a, unsigned b )
  3. {
  4.     unsigned long long ret = 1;

  5.     for( unsigned long long tmp=a; b; b>>=1, tmp*=tmp )
  6.     {
  7.         if( b&1 )
  8.             ret *= tmp;
  9.     }

  10.     return ret;
  11. }

  12. int main()
  13. {
  14.     printf( "3^35 = %llu\n", pown(3,35) ); // 50031545098999707
  15.     printf( "3^36 = %llu\n", pown(3,36) ); // 150094635296999121

  16.     return 0;
  17. }
复制代码
在VC++9.0上用C++方式编译,运行结果正确。
但在MinGW4.8.1上用C99方式编译,运行结果却不正确,因为MinGW不认识%llu,这简直是太扯淡了。
不得已,再改一下代码
  1. #include <stdio.h>
  2. #include <inttypes.h>

  3. uint64_t pown( unsigned a, unsigned b )
  4. {
  5.     uint64_t ret = 1;

  6.     for( uint64_t tmp=a; b; b>>=1, tmp*=tmp )
  7.     {
  8.         if( b&1 )
  9.             ret *= tmp;
  10.     }

  11.     return ret;
  12. }

  13. int main()
  14. {
  15.     printf( "3^35 = %"PRIu64"\n", pown(3,35) ); // 50031545098999707
  16.     printf( "3^36 = %"PRIu64"\n", pown(3,36) ); // 150094635296999121

  17.     return 0;
  18. }
复制代码

论坛徽章:
0
9 [报告]
发表于 2013-07-30 16:46 |只看该作者
回复 8# bruceteen


    请问一下  b>>=1这是什么运算?

论坛徽章:
0
10 [报告]
发表于 2013-07-30 16:52 |只看该作者
回复 8# bruceteen


    还有&与运算表示的是什么啊?我知道怎样运算但是不知道运算结果代表什么意思的。求解!跪谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP