C#解惑01: 奇数性

谜题01: 奇数性

下面方法的目的是确定其唯一的参数是否为奇数。这个方法可行吗?

public static bool IsOdd(int i)

{

return i % 2 == 1;

}

解惑01: 奇数性

奇数可定义为被2整除余数为1的整数。表达式i%2计算的是i除以2时所产生的余数,因此看起来这个程序应该可行。遗憾的是,它不行;在四分之一的时间里它返回的都是错误的答案。

为什么是四分之一?因为在所有的int数值中,有一半是负数,而IsOdd方法对所有负奇数的判断都会失败。在任何负整数上调用该方法都会返回false,无论该整数是偶数还是奇数。

这是C#对取余操作符(%)的定义所产生的后果。该操作符被定义为对所有的int数值a和所有的非零int数值b,都满足下面的恒等式:

(a / b) * b + (a % b) == a

换句话说,如果用b整除a,将商乘以b,然后加上余数,那么就得到了最初的值a[C#语言规范
7.7.3]
。该恒等式具有正确的含义,但是当与C#的截尾整数整除操作符[C#语言规范
7.7.2]
相结合时,它就意味着:当取余操作返回一个非零的结果时,它与左操作数具有相同的正负符号。

IsOdd方法以及它所基于的对术语“奇数”的定义都假设所有的余数都是正数。虽然该假设对某些种类的整除是有意义的,但是C#的取余操作是与舍弃整除结果小数部分的整数整除操作完全匹配的。

当i是一个负奇数时,i % 2等于-1而不是1,因此IsOdd方法错误地返回false。为了防止这种意外,请测试你的方法在为每一个数值型参数传递负数、零和正数数值时,其行为是否正确。

这个问题很容易改正。只需将i % 2与0而不是与1比较,并且使用相反的比较含义即可:

public static bool IsOdd(int i)

{

return i % 2 != 0;

}

如果正在一个强调性能的环境中使用IsOdd方法,那么用位操作符AND(&)替代取余操作符会显得更好:

public static bool IsOdd(int i)

{

return (i & 1) != 0;

}

第二个版本运行起来可能比第一个版本要快得多,这取决于你使用的是什么样的平台和虚拟机,并且不太可能出现运行得更慢的情况。按常规来说,整除和取余操作与其他的算术和逻辑操作相比要慢一些。仓促地优化是不好的,但是在上述情况下,更快的版本与最初的版本一样清晰明白,所以没有任何理由偏爱最初的版本。

总之,无论何时使用了取余操作符,都要考虑操作数和结果的符号。该操作符的行为在其操作数非负时是一目了然的,但是当一个或两个操作数是负数时,它的行为就不那么显而易见了。

版权声明:本文为博主http://www.zuiniusn.com 原创文章,未经博主允许不得转载。

时间: 2024-10-09 20:11:13

C#解惑01: 奇数性的相关文章

我喜欢减肥我们来减肥吧

http://www.ebay.com/cln/honus.jyw4mvptb/cars/158313278016/2015.01.28.html http://www.ebay.com/cln/honus.jyw4mvptb/cars/158313282016/2015.01.28.html http://www.ebay.com/cln/honus.jyw4mvptb/cars/158313289016/2015.01.28.html http://www.ebay.com/cln/usli

百度回家看沙发沙发是减肥了卡斯加积分卡拉是减肥

http://www.ebay.com/cln/hpryu-caw8ke/cars/158056866019/2015.01.31 http://www.ebay.com/cln/xub.50x2l7cj/cars/158445650015/2015.01.31 http://www.ebay.com/cln/xub.50x2l7cj/cars/158445674015/2015.01.31 http://www.ebay.com/cln/xub.50x2l7cj/cars/1584456790

巢哑偕倥乇椭煞谙暗逞帕俸

IEEE Spectrum 杂志发布了一年一度的编程语言排行榜,这也是他们发布的第四届编程语言 Top 榜. 据介绍,IEEE Spectrum 的排序是来自 10 个重要线上数据源的综合,例如 Stack Overflow.Twitter.Reddit.IEEE Xplore.GitHub.CareerBuilder 等,对 48 种语言进行排行. 与其他排行榜不同的是,IEEE Spectrum 可以让读者自己选择参数组合时的权重,得到不同的排序结果.考虑到典型的 Spectrum 读者需求

我国第三代移动通信研究开发进展-尤肖虎200106

众所周知,数据科学是这几年才火起来的概念,而应运而生的数据科学家(data scientist)明显缺乏清晰的录取标准和工作内容.此次课程以<星际争霸II>回放文件分析为例,集中在IBM Cloud相关数据分析服务的应用.面对星际游戏爱好者希望提升技能的要求,我们使用IBM Data Science Experience中的jJupyter Notebooks来实现数据的可视化以及对数据进行深度分析,并最终存储到IBM Cloudant中.这是个介绍+动手实践的教程,参会者不仅将和讲师一起在线

pl/sql学习1——标量变量psahnh6S

为类型.不能用于表列的数据类型.范围为的子类型.自然数.为的子类型.具有约束为单精度浮点数.为变量赋值时.后面要加为双精度浮点数.为变量赋值时.后面要加.为数字总位数.为小数位数是的子类型.最大精度位是的子类型.最大精度位单精度浮点型是的子类型.最大精度位双精度浮点型定义精度为位的实数..定义为位的整数.变长字符串.最长测试变量数据!.定长字符串.最长测试变长二进制字符串物理存储的为类型...固定长度.个字节使用定义数据类型那个最小值:最大值:最小值:最大值:最小值:最大值:最小值:最大值:最小

解惑:NFC手机如何轻松读取银行卡信息?

自支付宝钱包8.0推出了NFC新功能,只要将支持NFC功能的手机靠近公交卡.银行卡等带有芯片的IC卡上,可迅速读取卡内余额.卡的信息,还可以给卡进行充值,非常贴心实用. 但是很多网友表示担忧,要是别人用手机紧贴着我的银行卡,那么信息不就轻易泄露了,这样会威胁我的资金安全吗?并有不少伪专家宣称,NFC手机有可能成为黑客的"提款机",可以实现转账操作,风险很大,网友表示很担心.真实情况是什么样的呢?让我从专业的角度,给大家道出内幕. NFC(近场通信,NearFieldCommunicat

《Java 解惑》笔记(一)

<Java 解惑>里都是一些编程时容易忽略的细节,却也蛮有意思的,所以将里面的内容稍作整理,简略地概括一下: 1.奇数性 在编程的时候经常会遇到要判断传进来的参数是否为奇数,而且容易惯性地认为判断余数是否为1即可,如下代码: public static boolean isOdd ( int i ) { return i % 2 == 1 } 这段程序在四分之一的时间里返回的都是错误的答案 因为在所有的 int 数值中,有一半都是负数,而 isOdd 方法对于对所有负奇数的判断都会失败.在任何

《Java解惑》读书笔记

 摘选自<Java解惑>一书,之前整理了部分,一直没看完,最近为了督促自己每天读点这本书,决定一天至少更新一个谜题的内容,欢迎讨论. 欢迎关注技术博客http://blog.sina.com.cn/u/1822488043 Java解惑读书笔记 谜题1:奇数性 取余操作的定义: ( a / b ) * b + ( a % b ) = a 其中(a/b)是java运算的结果,也就是a/b是一个整数,比如3/2=1. 所以当取余操作返回一个非零结果的时候,它与左操作数具有相同符号. 请测试你的

DWR3.0 服务器推送及解惑

前言 环境搭建 建立工程 jar包填装 下载dwrjar 下载commons-loggingjar 项目目录 webxml dwrxml java文件 jsp页面 调试运行 文字展示 图片展示 解惑篇 关于自动生成的js文件 如何配置页面脚本 客户端怎么调用服务器端方法 总结 前言 昨天晚上偶然咋慕课网上看到了一个DWR的视频,一开始我还以为是DreamWaver的缩写,后来发现我错了,原来人家是Direct Web Remoting的缩写. DWR说白了是一个用于改善web页面与Java类交互