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

[讨论] 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. gettimeofday(&start, NULL);
  13. for (j = 0; j < 1000; j ++)
  14. for (i = 0; i < 1000000; i ++)
  15. {
  16. d[i] = d[i] * 10;
  17. }
  18. gettimeofday(&end, NULL);
  19. t = (end.tv_sec - start.tv_sec) * 1.0 + (end.tv_usec - start.tv_usec) / 100000000.0;
  20. printf("* : %4.6f\n", t);
  21. gettimeofday(&start, NULL);
  22. for (j = 0; j < 1000; j ++)
  23. for (i = 0; i < 1000000; i ++)
  24. {
  25. d[i] = d[i] << 3 + d[i] << 1;
  26. }
  27. gettimeofday(&end, NULL);
  28. t = (end.tv_sec - start.tv_sec) * 1.0 + (end.tv_usec - start.tv_usec) / 100000000.0;
  29. printf("<< %4.6f\n", t);
  30. }
复制代码
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-11-23 08:46 , Processed in 0.023751 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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