• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >编程问答 > 如何只用一个加号计算三个数之和?

如何只用一个加号计算三个数之和?

作者:佚名 字体:[增加 减小] 来源:互联网 时间:2017-06-07

佚名通过本文主要向大家介绍了只用2和7两个自然数,尿常规隐血2个加号,尿常规潜血3个加号,html 加号,蛋白一个加号等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题:如何只用一个加号计算三个数之和?
描述:

四则运算符不能用减号乘号和除号,加号只能用一次,可以用其他运算符,不能用函数。
如何计算 α、β、γ 三个数之和?


解决方案1:

果断 Lisp 哇,(+ α β γ) 当然,Lisp 里 + 就是个函数

解决方案2:

修改了下 (a^b^c)+(((a&b)|(b&c)|(a&c))<<1) ..应该是这个了。。

解决方案3:

看着楼上真着急 ... 还是我来吧 ...

计算三个数字加和的方法是 ( a ^ b ^ c ) + ( ( ( a & b ) | ( b & c ) | ( a & c ) ) << 1 ) ...

楼上的结论是完全正确的 ... 但如果你要问这个公式是哪里来的 ... 你就要先弄明白什么是 加法 ...

还没学会如何迈开脚步又怎么能跑起来 ... 三个数字之前 ... 我们先要从两个数字相加开始 ...

首先你要知道计算机里面的数字都是以二进制存储的 ... 你看到的数字 ... 在计算机看来都是 0 和 1 ...

我们随便挑两个数字比如 123 和 321 ... 转化成二进制之后用用竖式把它们加在一起 ...

    '    "' 
   001111011  = 123
 + 101000001  = 321
-------------
   110111100  = 444

相同位置对齐 ... 从个位数加起 ... 相加的结果满二进一 ... 这个不用我多说了吧 ..?

你可能会注意到 ... 在竖式的上方我有加 ' 和 " 符号 ... 这表示进位 ...

这两个符号的区别是 ' 表示由原来的数字产生的进位 ... " 表示由 ' 产生的进位 ...

不过事实上 ... 进位这个事情本身也是二进制 ... 0 和 1 嘛 ... 所以不妨就用二进制来表示 ...

把所有由原来的数字产生的进位也就是 ' 写成 1 ... 其他填 0 ... 结果像这样 ...

   001111011  ( a
   101000001  ( b
   010000010  ( c

我们得到了三个数字 ... a 和 b 是原来的数字 ... c 是进位 ...

回想我们刚刚竖式计算的过程 ... 是不是每次都是先计算一位的值 ... 然后再看有没有进位要加 ..?

我们现在用程序模拟这个过程 ... 不考虑进位的时候先把 a 和 b 相加 ...

在只有一位的时候 ... 0 ^ 0 = 01 ^ 0 = 10 ^ 1 = 11 ^ 1 = 0 ... 只有这四种情况 ...

不知道你有没有发现 ... 在这种情况下 ... 我没有使用 + 而是用 ^ 得到了同样正确的结果 ...

^ 就是位运算操作符里面的 按位异或 ... 简单的解释就是两个数字相同就返回 0 不同就返回 1 ...

关于位运算可以看我在另一个问题里的回答 http://sfau.lt/bNVhO ... 这里就不再赘述了 ...

总之 ... a 和 b 不进位相加之后 ... 我们的式子变成了这样 ...

         '
   010000010  ( c
 + 100111010  ( d
-------------
   110111100  = 444

其中 d = a ^ b ... 我们就这样成功把 a 和 b 相加的问题转化成了 c 和 d 相加的问题 ...

但是同时又出现了新的问题 ... 怎么得到 c ..?

回想一下 ... c 是怎么来的 ..? 是由进位转化来的 ... 进位又是怎么来的 ..? 满二进一 ...

也就是当 a 和 b 的某一位同时为 1 的时候 ... c 的相应位置的左边一位为 1 ...

换言之 ... 当 a 和 b 的左起第 n + 1 位同时为 1 的时候则 c 的左起第 n 位为 1 ...

用式子来描述就是 c = ( a & b ) << 1 ...

& 是位运算操作符里面的 按位与 ... << 是位运算操作符里面的 左移 ...

如果你认真看了我刚刚说的那个在另外问题里的回答的话 ... 应该不会对这两个操作符有疑问 ...

到现在为止 ... 我们又把 c 和 d 转化回了与 a 和 b 相关的式子 ...

总结一下 ... 不考虑进位的计算结果是 a ^ b ... 进位的部分是 ( a & b ) << 1 ...

所以我们可以得到结论 ... a + b = ( a ^ b ) + ( ( a & b ) << 1 ) ...

绕了一大圈 ... 我们学会了怎么把两个数相加改为另外两个数相加 ...

这个看似没用的式子 ... 恰恰是解决这道题的关键 ...

如果你愿意 ... 可以一直这么写下去 ... 比如把这个式子继续拆分变成下面的样子 ...

(a ^ b) ^ ( ( a & b ) << 1 ) + ( ( a ^ b ) & ( ( a & b ) << 1 ) )

然后继续继续 ... 直到最右边那一项左移若干次之后变成 0 ... 你就实现了完全不用加号的加法 ...

在这个时候 ... 你加上一个新的数字 ... 就实现了一个加号的三个数字相加 ...

当然如果你仍然愿意继续的话 ... 甚至可以实现不用加号的三个数字相加 ...

唯一的问题就是最终的式子会长到一个屏幕都显示不下 ... 各种没法看 ...

所以我们现在回归最初 ... 继续列竖式 ... 看看三个数相加的时候到底发生了什么 ...

我们再随便挑三个数字 ... 比如 111 222 和 333 ...

   ""#""##''
   0001101111  = 111
   0011011110  = 222
 + 0101001101  = 333
--------------
   1010011010  = 666

和之前一样 ' 表示由原来的数字产生的进位 ... " 表示由 ' 产生的进位 ...

新增的 # 表示原来的数字在这里会产生进位但由于 ' 或 " 的原因发生了左移的进位位置 ...

我们同样把这个进位表示为二进制 ... ' 和 # 记为 1 其他记为 0 ... 如下 ...

   0001101111  ( a
   0011011110  ( b
   0101001101  ( c
   0010011110  ( d

我觉得都到现在了 ... 不用我说你应该也可以看出规律了吧 ...

只要 a b c 三个数字的某一位至少有两个为 1 ... 在 d 的相应位置的左边一位就为 1 ...

用式子来描述就是 d = ( ( a & b ) | ( b & c ) | ( a & c ) ) << 1 ...

| 是位运算操作符里面的 按位或 ... 对比三个数字找到是否有某两个数字的同一位都为 1 ...

进位算出来之后 ... 不考虑进位的计算结果是什么就不用我说了吧 ..?

现在再回去看看最开始说过的那个公式 ... 是不是觉得豁然开朗了呢 ..?

终于写完了 ... 这个回答写了快两个小时 ... 最后写的头都大了 ... 完全不知道自己在说什么了已经 ...

答案里不一定都对 ... 有错误的地方欢迎指正 ...

教导小朋友果然是体力活 ... 求安慰 ...

以及 ... 最后给你留一道思考题 ... 你要是能做出来的话也不枉我费了这么大力气写了这么多 ...

实现不用乘号的两个数相乘 ... 如果你能做出来就是真明白了 ...

恩恩就是这样啦 ...


分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 如何只用一个加号计算三个数之和?

相关文章

  • 2017-06-07 用uploadify上传不成功,一直返回HTTPError400
  • 2017-06-07 Python编码问题?
  • 2017-06-07 七牛的js-sdk谁会用啊,我不会nodejs啊
  • 2017-06-07 请问,七牛的公开空间ajax跨域请求可靠吗?
  • 2017-06-07 七牛:php生成带多个策略的token的问题
  • 2017-06-07 python爬虫python中的空tuple有什么用呢?
  • 2017-06-07 Python如何实现倒计时效果?
  • 2017-06-07 mac下有什么好的机械键盘么?
  • 2017-06-07 用相同key上传不同文件会产生什么结果?
  • 2017-06-07 Flask中服务器端怎样接受ajax发送的json?

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 不同IP对一个php上千万次请求,是cc攻击吗?怎么防?
    • (ruby)bundleexecjekyllserve出错
    • (python)pycharm中文长注释报错但运行正常interpreter是351
    • (python)flask会话中重定向问题
    • php中如何解决函数参数列表过长问题
    • 求PHP上传BASE64图片字符窜,上后能能访问图片
    • (python)我写的Xpath为什么爬取不到内容
    • (python)在计算机时间不准确的情况下,怎么循环执行某个函数?
    • Python字符转义
    • java使用ArrayList时提示超出索引范围,如图

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有