一个循环体引发的思考

/*
* 计算 n*(n-1)*……(n-k) / 1*2*3……*k
* 循环要找到循环体

*/

忽略上面格式的问题,其实我只想说 如果要用一个for循环来计算这个结果,当然按照字面意思,我们可以不假思索的写到

for循环 计算出  n*(n-1)*……(n-k)  的结果

然后再用for循环计算出 1*2*3……*k的结果 然后再相除,但是其实只要我们把这个计算公式做个简单的变形,我们只需要一个for循环就可以计算出这个结果,

所以我明白了一个道理   用for循环尽量简便的找到循环体 和 循环条件,这样 使得 写法简便,但不一定是最好理解的。

n/k  *   (n-1)/(k-1)  * (n-2)/(k-2)  ....  (n-k)/1 一共是k-1项  所以你是不是发现这样很好做了? 但如果你以为就这么简单的话 我还有必要写一个博客嘛?

这里还有一个陷阱,我们知道 java在计算除法时 结果默认为整形,比如 3/2 =1, 所以 这里这么多除法运算 你还需要借助一个 BIgDecimal 类 来处理,这个类是java自带的类,当然 它用起来极其麻烦,因为里面用的运算 都是通过调用里面的方法来实现的,并且参数类型是 BigDecimal 类 ,这 时候 你就需要自己写个封装类 封装下这层的函数 使得你调用方法简便,快捷, 下面是网上找来的例子:

package xy.base;


import java.math.BigDecimal;


public   class   Arith{    
    
    //默认除法运算精度    
    private   static   final   int   DEF_DIV_SCALE   =   10;    


    //这个类不能实例化    
    private   Arith(){    
    }    
    /**   
      *   提供精确的加法运算。   
      *   @param   v1   被加数   
      *   @param   v2   加数   
      *   @return   两个参数的和   
      */    
    public   static   double   add(double   v1,double   v2){    
            BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));    
            BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));    
            return   b1.add(b2).doubleValue();    
    }    
    /**   
      *   提供精确的减法运算。   
      *   @param   v1   被减数   
      *   @param   v2   减数   
      *   @return   两个参数的差   
      */    
    public   static   double   sub(double   v1,double   v2){    
            BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));    
            BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));    
            return   b1.subtract(b2).doubleValue();    
    }      
    /**   
      *   提供精确的乘法运算。   
      *   @param   v1   被乘数   
      *   @param   v2   乘数   
      *   @return   两个参数的积   
      */    
    public   static   double   mul(double   v1,double   v2){    
            BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));    
            BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));    
            return   b1.multiply(b2).doubleValue();    
    }    


    /**   
      *   提供(相对)精确的除法运算,当发生除不尽的情况时,精确到   
      *   小数点以后10位,以后的数字四舍五入。   
      *   @param   v1   被除数   
      *   @param   v2   除数   
      *   @return   两个参数的商   
      */    


    public   static   double   div(double   v1,double   v2){    
            return   div(v1,v2,DEF_DIV_SCALE);    
    }    


 


    /**   
      *   提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指   
      *   定精度,以后的数字四舍五入。   
      *   @param   v1   被除数   
      *   @param   v2   除数   
      *   @param   scale   表示表示需要精确到小数点以后几位。   
      *   @return   两个参数的商   
      */    


    public   static   double   div(double   v1,double   v2,int   scale){    
            if(scale<0){    
                    throw   new   IllegalArgumentException(    
                            "The   scale   must   be   a   positive   integer   or   zero");    
            }    
            BigDecimal   b1   =   new   BigDecimal(Double.toString(v1));    
            BigDecimal   b2   =   new   BigDecimal(Double.toString(v2));    
            return   b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();    
    }    


 


    /**   
      *   提供精确的小数位四舍五入处理。   
      *   @param   v   需要四舍五入的数字   
      *   @param   scale   小数点后保留几位   
      *   @return   四舍五入后的结果   
      */    


    public   static   double   round(double   v,int   scale){    
            if(scale<0){    
                    throw   new   IllegalArgumentException(    
                            "The   scale   must   be   a   positive   integer   or   zero");    
            }    
            BigDecimal   b   =   new   BigDecimal(Double.toString(v));    
            BigDecimal   one   =   new   BigDecimal("1");    
            return   b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();    
    }    
}; 


都有说明,按照这样的方式调用就好了。


其实虽然做开发时间还算蛮长的了,但一直感觉自己是个low逼,因为感觉心中没有一个写代码的准则,所以又回顾基础知识。到这里 这个循环差不多算是了结了。


下面要说一下可能大部分老手都不一定理解的东西,编码字符集问题:

首先 你要明白 byte char 这对象的含义, byte表示一个字节  一个字节是八位二进制数,这个你知道吧,那么char 表示一个字符,不同的字符集所需要的字节数不一定相同,这里只说下 java内部是用的Unicode字符集,用两个字节 表示一个字符,这里又要介绍另一个术语,代码单元,它就表示一个字符的长度,“A我 ” 表示两个代码单元,四个字节。

还有一个代码点,它是和Unicode的字符集对应的,这个要讲到它的起源,是因为考虑到加入中文,所以原本的八位二进制不够用了,就用了十六位,那么每个数字代表的就是一个代码点。 那么和utf-8是什么关系呢,这个不叫字符集,网上有很多不懂或者一知半解的人乱说,它表示编码的格式,同类的有 GBK...,那么这些编码方式对应的是 在这些数据传输过程中 是怎么进行编码转换的,因为 Unicode字符集 对英文的二进制表示也是十六位,对资源来说是一种浪费,所以就提出了将数据进行编码,数据中英文的还是一个字节表示,中文的用2-4个字节表示,这么说明白了嘛。至于 这之中是怎么转化的 是有一个算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值