找回密码
 欢迎注册
楼主: 无心人

[讨论] 10^n的二进制表示

[复制链接]
 楼主| 发表于 2009-1-12 11:37:38 | 显示全部楼层
对乘以10的测试表明
在Core 2 XEON /1.6上重复10^9次
两者均是5s, 移位操作稍微多点

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/time.h>

  4. int d[1000000];

  5. int main(void)
  6. {
  7.   int i, j, k;
  8.   double t;
  9.   struct timeval start, end;

  10.   for (i = 0; i < 1000000; i ++)
  11.     d[i] = i << 8;
  12.   
  13.   gettimeofday(&start, NULL);
  14.   for (j = 0; j < 1000; j ++)
  15.   for (i = 0; i < 1000000; i ++)
  16.   {
  17.     d[i] = d[i] * 10;
  18.   }
  19.   gettimeofday(&end, NULL);  
  20.   
  21.   t = (end.tv_sec - start.tv_sec) * 1.0 + (end.tv_usec - start.tv_usec) / 100000000.0;
  22.   printf("* : %4.6f\n", t);

  23.   gettimeofday(&start, NULL);
  24.   for (j = 0; j < 1000; j ++)
  25.   for (i = 0; i < 1000000; i ++)
  26.   {
  27.     d[i] = d[i] << 3 + d[i] << 1;
  28.   }
  29.   gettimeofday(&end, NULL);  
  30.   
  31.   t = (end.tv_sec - start.tv_sec) * 1.0 + (end.tv_usec - start.tv_usec) / 100000000.0;
  32.   printf("<< %4.6f\n", t);

  33. }
复制代码
E:\MinGW\MSYS\math>mul10
* : 5.006406
<< 6.000781

E:\MinGW\MSYS\math>mul10
* : 5.995781
<< 6.000625

E:\MinGW\MSYS\math>mul10
* : 5.995938
<< 6.001250

E:\MinGW\MSYS\math>mul10
* : 5.996094
<< 6.001406
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-1-12 11:40:59 | 显示全部楼层
* 100和 << 6 + << 5 + << 2比较
E:\MinGW\MSYS\math>mul10
* : 6.002344
<< 6.997813

E:\MinGW\MSYS\math>mul10
* : 6.002500
<< 6.997813

E:\MinGW\MSYS\math>mul10
* : 6.002500
<< 6.997813
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-12 11:43:57 | 显示全部楼层
编译器也可能将乘法进行优化的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-1-12 11:44:49 | 显示全部楼层
* 1000
<< 10 - << 4 - << 3
E:\MinGW\MSYS\math>mul10
* : 6.996250
<< 6.007813

E:\MinGW\MSYS\math>mul10
* : 6.006250
<< 6.997813

E:\MinGW\MSYS\math>mul10
* : 6.006406
<< 6.997656
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-1-12 11:48:12 | 显示全部楼层
在*10000   <<13 + <<11 -<<8 + <<4时
移位开始超越乘法
E:\MinGW\MSYS\math>mul10
* : 9.000156
<< 8.996250

E:\MinGW\MSYS\math>mul10
* : 9.000937
<< 8.006562

E:\MinGW\MSYS\math>mul10
* : 9.000312
<< 8.996250

E:\MinGW\MSYS\math>mul10
* : 9.000312
<< 8.996562
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-12 11:48:43 | 显示全部楼层
编译器对于常数的乘除法确实可能智能优化,
但对于大整数的整体优化应该不会。
(我的意思是 M*10 <-- (M<<3)+(M<<1),M 为大整数)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-1-12 11:49:45 | 显示全部楼层
是关闭优化设置的
而且,你看程序
编译器很难优化掉乘法的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-12 11:55:37 | 显示全部楼层
原帖由 无心人 于 2009-1-12 11:48 发表
在*10000   

这个结果不说明任何问题。测量结果应该完全由误差引起(注意Windows下通常时钟精度也就是20毫秒),甚至有可能两端代码编译器优化后完全类似
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-12 12:43:51 | 显示全部楼层
10^n的二进制表示

看0和1出现次数?

1的出现次数大于0的出现次数,使用 减
否则使用加

10=1010
+2^3+2^1
100=1100100
+2^6+2^5+2^2
1000=1111101000
-2^3-2^4+2^10
10000=10011100010000
+2^13+2^10+2^9+2^8+2^4
100000=11000011010100000
+2^16+2^15+2^10+2^9+2^7+2^5
.................
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-1-12 13:18:18 | 显示全部楼层
d[i] = d[i] << 3 + d[i] << 1;
需要括号吧?这段代码改成
int di = d[i];
d[i] = (di << 3) + (di << 1);
或许会快点
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-5-19 17:58 , Processed in 0.094062 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表