精华内容
下载资源
问答
  • 做题的时候可能会遇到需要判断 比如2193中是否含有7这个数字的要求。 办法有很多,记录一种自己认为简单的方法: 先把这个数字转变为字符串形式, String.valueOf(2017) 用string的indexOf函数,计算字符“7”的...

    做题的时候可能会遇到需要判断 比如2193中是否含有7这个数字的要求。

    办法有很多,记录一种自己认为简单的方法:

    • 先把这个数字转变为字符串形式, String.valueOf(2017)
    • 用string的indexOf函数,计算字符“7”的下标,
    • 如果下标是-1,则说明不存在;
    • 如果下标不等于-1,则说明找到了。
    /**
     * 先把这个数字转变为字符串形式,
     * 用string的indexof函数,计算字符“7”的下标,
     * 如果下标是-1,则说明不存在;
     * 如果下标不等于-1,则说明找到了。
     */
    int i = 2020;
    String string = String.valueOf(i);
    int index = string.indexOf("7");
    if(i % 7 == 0 || index != -1){
    	arr[(i-1)%4]++;
    }else{
    	total++;
    }
    i++;
    
    
    展开全文
  • Java poi Excel xls数字转字母

    千次阅读 2016-12-02 16:24:42
    最近遇到导出的xls中 是动态生成的,且单元格中需要用到公式,而xls公式不是用数字列号而是用字母来表示的,这时需要把数字号转成该对应的字母。因为是按月导出 一个月最多31天,所以刚开始采用的办法是...

    最近遇到导出的xls中 列是动态生成的,且单元格中需要用到公式,而xls公式不是用数字列号而是用列字母来表示的,这时需要把数字的列号转成该列对应的字母。因为是按月导出 一个月最多31天,所以刚开始采用的办法是定义一个包含1到31列字母的数组。后来想想这样总不是个办法 万一列数更多 且是不确定的呢。于是研究了下 怎么把xls数字列号转成对应的字母。

    先来看xlsx中的字母规律。在xls中,1到26列是A~Z,从第27列开始 是2个以上的字母组合 AA AB ... AZ 然后到BA BB ... BZ 直到 ZA ZB ... ZZ 这时两个字母的组合完了 接下来到3个字母 AAA AAB ... AAZ 然后到ABA ABB ... ABZ 一直到AZZ 然后是BAA BAB ... BZZ最后到ZAA ... ZZZ,接下来又是4个字母的组合如此循环...  。

    于是发现了规律: AA~AZ是在A~Z前面加了A,BA~BZ是在A~Z前面加了B,... ZA~ZZ是在A~Z前面加了Z,这时两个字母组合完毕;到3个字母 AAA~AAZ是在AA~AZ前面加了A,ABA~ABZ是在BA~BZ前面加了A,... AZA~AZZ是在ZA~ZZ前面加了A,这时AA~ZZ遍历完了一次(这里的AA~ZZ是前面两个字母组合里出现过的);接下来到下一轮遍历 在前面加B,BAA~BAZ是在AA~AZ前面加了B,... BZA~BZZ是在ZA~ZZ前面加了B,这时AA~ZZ又遍历完了一次;再进行下一轮遍历 一直到在所有两个字母的组合前都加过A~Z,这时3个字母的组合就全部组合完毕了。接下来到4个字母的组合 跟前面的2个、3个字母的组合类似,都是在上一个组合的基础上分别在前面加上A~Z。如下图


    字母组合是从第27列开始,每次的组合都是在上一个组合的基础上分别在前面加上A~Z。比如计算n=3个字母的组合AAA~ZZZ(上图红色竖线箭头部分):2个字母组合所在的范围是AA~ZZ(上图红色的“currentLen”部分),当前数组的位置(比如AAB)i与currentLen进行取余运算(i%currentLen)得到的结果就是要与2个字母组合的哪个种组合进行字符串拼接(该值还要与“lastLen”(上图红色lastLen)相加才能定位到该位置对应的字母),比如当前是第一轮遍历 则是A与AB进行拼接成AAB,这也就是上面举例的当前数组位置对应的字母(AAB)。假设我们用变量letterIdx表示第几轮,每上个组合遍历完一次letterIdx都要+1,表示下一个要拼接在前面的字母。因为拼接在前面的字母是A~Z 所以每次取该轮字母时都要跟26取余(letterIdx%26),当letterIdx%26=0时 说明A~Z都与上个组合拼接过了 也就是当前n个字母组合所有情况都组合过了,再进行下一轮n+1个(4个)字母的组合(上图黑色竖线箭头部分),这时currentLen变成了上一个组合的长度(上图黑色的currentLen),而lastLen变成了“上个组合的currentLen+lastLen”(上图黑色的lastLen部分),接下来的循环遍历跟上个组合一样进行。

    上代码:(代码里的注释请结合上文来看,注释里说到的“组合的情形”是指该组合的某一种组合,如BK、AH、XI都是2个字母组合的一种情形。因为实在也不知道应该用哪个词来表达)

    public final class Columns {
    
    	private Columns() {}
    
    	private static String[] sources = new String[]{
    		"A","B","C","D","E","F","G","H",
    		"I","J","K","L","M","N","O","P",
    		"Q","R","S","T","U","V","W","X","Y","Z"
    	};
    
    	/**
    	 * (256 for *.xls, 16384 for *.xlsx)
    	 * @param columnNum 列的个数,至少要为1
    	 * @throws IllegalArgumentException 如果 columnNum 超出该范围 [1,16384]
    	 * @return 返回[1,columnNum]共columnNum个对应xls列字母的数组
    	 */
    	public static String[] getColumnLabels(int columnNum) {
    		if(columnNum<1||columnNum>16384)
    			throw new IllegalArgumentException();
    		String[] columns = new String[columnNum];
    		if(columnNum<27){	//小于27列 不用组合
    			System.arraycopy(sources, 0, columns, 0, columnNum);
    			return columns;
    		}		
    		System.arraycopy(sources, 0, columns, 0, 26);	//前26列不需要进行组合
    
    		//因为基于数组是从0开始,每到新一轮letterIdx 会递增,所以第一轮 在递增前是-1
    		int letterIdx = -1;
    		int currentLen = 26;//第一轮组合(2个字母的组合)是分别与A-Z进行拼接 所以是26
    		int remainder;
    		int lastLen = 0;	//用于定位上文提到的i%currentLen实际在数组中的位置		
    		int totalLen = 26;	//totalLen=currentLen+lastLen
    		int currentLoopIdx = 0; //用来记录当前组合所有情形的个数
    
    		for(int i=26;i<columnNum;i++){ //第27列(对应数组的第26个位置)开始组合
    
    	//currentLen是上个组合所有情形的个数,与它取余找到要与上个组合的哪种情形进行拼接
    			remainder = currentLoopIdx%currentLen;
    
    			if(remainder==0){
    				letterIdx++; //完成一次上个组合的遍历,转到下个字母进行拼接
    				int j = letterIdx%26;
    
    			//A-Z 26个子母都与上个组合所有情形都进行过拼接了,需要进行下个组合的拼接
    				if(j==0&&letterIdx!=0){ 
    					lastLen = totalLen; //下个组合的lastLen是上个组合的totalLen
    
    				/**
    	 		     * 下个组合的currentLen是上个组合的所有组合情形的个数
    	 		     * (等于上个组合的currentLen*26),26也就是拼接在前面的A-Z的个数
    	 		     */			 
    					currentLen = 26*currentLen;
    
    					totalLen = currentLen+lastLen; //为下一轮的开始做准备
    					currentLoopIdx = 0; //到下一轮了 因此需要重置
    				}
    			}
    			/**
    	 	     * sources[letterIdx%26]是该轮要拼接在前面的字母
    	 	     * columns[remainder+lastLen]是上个组合被拼接的情形
    	 	     */		
    			columns[i] = sources[letterIdx%26]+columns[remainder+lastLen];
    			currentLoopIdx++;
    		}
    		return columns;
    	}
    }
    测试:
    public static void main(String[] args) {
    	String[] columns = getColumnLabels(37 );
    	System.out.println("1到37列:"+Arrays.toString(columns));
    	System.out.println();
    	long start = System.nanoTime();
    	columns = getColumnLabels(256);
    	System.out.println("创建"+columns.length+"列用时(纳秒):"
    					   +(System.nanoTime()-start));
    	System.out.println("xls第"+columns.length+"列:"
    					   +columns[columns.length-1]);
    	System.out.println();
    	start = System.nanoTime();
    	columns = getColumnLabels(16384);
    	System.out.println("创建"+columns.length+"列用时(纳秒):"
    					   +(System.nanoTime()-start));
    	System.out.println("xlsx第"+columns.length+"列:"
    					   +columns[columns.length-1]);
    }

    打印:
    1到37列:[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, 
    U, V, W, X, Y, Z, AA, AB, AC, AD, AE, AF, AG, AH, AI, AJ, AK]
    
    创建256列用时(纳秒):192833
    xls第256列:IV
    
    创建16384列用时(纳秒):9574147
    xlsx第16384列:XFD

    ------------------------------------------------------分隔线-----------------------------------------------------------------

    后来有想到,如果是不需要(或者条件不允许)提前创建(这么大的)数组呢,这时需要通过列号直接获取该列对应的字母。于是又想 应该怎么转换。。。
    先看看从字母转数字的,比如BGQCV 转成数字(虽然xlsx最后一列是XFD,这里只讨论数字与字母的互转):该列标有5个字母,说明前面已经有4个字母、3、2、1个字母的全组合了 才会到5个字母的组合,于是W1=26^4+26^3+26^2+26^1,BGQCV 的第一个字母是B,说明前面有Axxxx的全组合了,于是有该组合数T1=1*(26^4)。再来看第二个字母是G,说明前面已经有BAxxx~BFxxx的全组合了,于是有该组合数T2=6*(26^3)。第三个字母是Q,说明前面已经有BGAxx~BGPxx的全组合了,于是有该组合数T3=16*(26^2)。第四个字母是C,说明前面已有BGQAx~BGQBx的全组合了,该组合数T4=2*(26^1)。最后一个字母是V,说明前缀是BGQC的组合BGQCA~BGQCV共有T5=22个。
    好了,BGQCV 所处的列数W=W1+T1+T2+T3+T4+T5=(26^4+26^3+26^2+26^1)+1*(26^4)+6*(26^3)+16*(26^2)+2*(26^1)+22 = 1048576。
    String[] sources = new String[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
    数组sources作为我们解决问题的字母来源(当然也可以不定义数组而是用ASCII码)。
    现在知道了通过字母列标是如何求出其对应的第几列,我们把问题一般化:求第W列对应的列标。设第W列对应的字母有n个,根据上面的分析可知W1=26^(n-1)+26^(n-2)+26^(n-3)+...+26^2+26^1。我们规定A对应1,B对应2 ... Z对应26。设第1个字母对应数字是num_1,第二个字母对应的数字是num_2,...,第n个字母对应数字num_n。根据上面的分析 于是有T1=(num_1-1)*26^(n-1),T2=(num_2-1)*26^(n-2),...,Tn=(num_n-1)*26^0。
    整合起来,又因为26^0=1 于是有W=W1+T1+T2+...+Tn=(26^(n-1)+26^(n-2)+26^(n-3)+...+26^2+26^1)+(num_1-1)*26^(n-1)+(num_2-1)*26^(n-2)+...+(num_(n-1)-1)*26^1+(num_n-1)。
    除了最右边的字母(也就是第n个字母)对应的位置的数字num_n-1除外,其它字母对应的位置的数字均是26的倍数。于是  第一次W对26取余W%26的结果所对应的字母(还记得吗 我们用1代表A,2代表B,... ,26代表Z)就是最右边的字母。好了 现在已经求出了最右边的字母,还剩n-1个未知字母,采用同样的办法可求出次右边的字母:W-(num_n-1)然后再除以26,得到的结果再减去1(因为W1中存在26^1,其除以26后结果就是1,为了保证除了次右边字母对应的位置的数字外,其余各字母对应的位置的数字均是26的倍数),把结果赋回给W,这时求次右边的字母就跟求最右边的字母类似了:
    W-(num_n-1)=(26^(n-1)+26^(n-2)+26^(n-3)+...+26^2+26^1)+(num_1-1)*26^(n-1)+(num_2-1)*26^(n-2)+...+(num_(n-1)-1)*26^1
    然后两边除以26:(W-(num_n-1))/26=(26^(n-2)+26^(n-3)+26^(n-4)+...+26^1+1)+(num_1-1)*26^(n-2)+(num_2-1)*26^(n-3)+...+(num_(n-1)-1)
    然后两边再减去1:(W-(num_n-1))/26-1=(26^(n-2)+26^(n-3)+26^(n-4)+...+26^1)+(num_1-1)*26^(n-2)+(num_2-1)*26^(n-3)+...+(num_(n-1)-1)
    然后把左边的(W-(num_n-1))/26-1看成整体的W,是不是跟最开始求最右边字母的很类似?
    这样从右往左求出来的字符串 跟所要的结果恰好是相反的 所要需要反转。
    上代码:
    /**
     * 返回该列号对应的字母
     * @param columnNo (xls的)第几列(从1开始)
     */
    public static String getCorrespondingLabel(int columnNo){
    	if(columnNo<1/**||columnNo>16384**/)
    		throw new IllegalArgumentException();
    	String[] sources = new String[]{"A","B","C","D","E","F","G","H","I","J","K","L","M"
    		,"N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
    	StringBuilder sb = new StringBuilder(5);
    	int remainder = columnNo%26;	//求最右边的字母
    	if(remainder==0){	//说明(num_n-1)=26,第26个字母是Z
    		sb.append("Z");
    		remainder = 26;	//因为接下来W-(num_n-1)也就是columnNo-remainder,所以需要把remainder赋值回26
    	}
    	else{  //如果最右边字母不是Z的话,就去sources数组相应的位置取字母,remainder不用变
    	  sb.append(sources[remainder-1]);
    	}
    	columnNo = (columnNo-remainder)/26-1;	//用来判断接下来是否还有其他字母
    
    	//当 当前循环是求最后一个字母时(从右往左),(columnNo-remainder)/26就会是0,再减1也就是-1。
    	//因此通过判断(columnNo-remainder)/26-1是否大于-1来判断结束
    	while(columnNo>-1){
    		remainder = columnNo%26;
    		sb.append(sources[remainder]);
    		columnNo = (columnNo-remainder)/26-1;
    	}
    
    	return sb.reverse().toString();	//因为是从右往左解析的 所以需要反转
    }


    测试:
    public static void main(String[] args) {
    	String label = getCorrespondingLabel(37 );
    	System.out.println("第37列:"+label);
    	System.out.println();
    	long start = System.nanoTime();
    	label = getCorrespondingLabel(256);
    	System.out.println("查找第256列对应字母 用时(纳秒):"
    					   +(System.nanoTime()-start));
    	System.out.println("xls第256列:"+label);
    	System.out.println();
    	
    	label = getCorrespondingLabel(16384);
    	
    	System.out.println("xlsx第16384列:"+label);
    }
    打印:
    第37列:AK
    
    查找第256列对应字母 用时(纳秒):7776
    xls第256列:IV
    
    xlsx第16384列:XFD
    这时又想到,求n列列标 用方法1好一点呢 还是用方法2循环n次好呢。。。
    方法1求数组的 对于26+26*26=702列以下,可以将求组合部分抽出来,减少不必要的求余运算multiple%26,因为这时multiple不会超过26。方法2也可以改成从0开始的 毕竟poi列数是从0开始的。不预定义字母数组的话 也可以用ASCII码来转换。
    -----------------------------------------------分隔线-----------------------------------------------------

    最终代码:

    /**
     * 
     * Excel列号转字母工具类
     * 
     */
    public final class Columns {
    
    	private Columns() {
    	}
    
    	private static String[] sources = new String[] { "A", "B", "C", "D", "E",
    			"F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
    			"S", "T", "U", "V", "W", "X", "Y", "Z" };
    
    	/**
    	 * (256 for *.xls, 16384 for *.xlsx)
    	 * 
    	 * @param columnNum
    	 *            列的个数,从1开始
    	 * @throws IllegalArgumentException
    	 *             如果 columnNum 超出该范围 [1,16384]
    	 * @return 返回[1,columnNum]共columnNum个对应xls列字母的数组
    	 */
    	public static String[] getColumnLabels(int columnNum) {
    		if (columnNum < 1 || columnNum > 16384)
    			throw new IllegalArgumentException();
    		String[] columns = new String[columnNum];
    		if (columnNum < 27) {
    			System.arraycopy(sources, 0, columns, 0, columnNum);
    			return columns;
    		}
    		int multiple = -1;
    		int remainder;
    		System.arraycopy(sources, 0, columns, 0, 26);
    		int currentLoopIdx = 0;
    		if (columnNum < 703) {
    			for (int i = 26; i < columnNum; i++) {
    				remainder = currentLoopIdx % 26;
    				if (remainder == 0) {
    					multiple++;
    				}
    				columns[i] = sources[multiple] + columns[remainder];
    				currentLoopIdx++;
    			}
    		} else {
    			int currentLen = 26;
    			int totalLen = 26;
    			int lastLen = 0;
    			for (int i = 26; i < columnNum; i++) {
    				remainder = currentLoopIdx % currentLen;
    				if (remainder == 0) {
    					multiple++;
    					int j = multiple % 26;
    					if (j == 0 && multiple != 0) {
    						lastLen = totalLen;
    						currentLen = 26 * currentLen;
    						totalLen = currentLen + lastLen;
    						currentLoopIdx = 0;
    					}
    				}
    				columns[i] = sources[multiple % 26]
    						+ columns[remainder + lastLen];
    				currentLoopIdx++;
    			}
    		}
    
    		return columns;
    	}
    
    	/**
    	 * 返回该列号对应的字母
    	 * 
    	 * @param columnNo
    	 *            (xls的)第几列(从1开始)
    	 */
    	private static String getCorrespondingLabel(int columnNo) {
    		if (columnNo < 1/** ||columnNo>16384 **/
    		)
    			throw new IllegalArgumentException();
    
    		StringBuilder sb = new StringBuilder(5);
    		int remainder = columnNo % 26;
    		if (remainder == 0) {
    			sb.append("Z");
    			remainder = 26;
    		} else {
    			sb.append(sources[remainder - 1]);
    		}
    
    		while ((columnNo = (columnNo - remainder) / 26 - 1) > -1) {
    			remainder = columnNo % 26;
    			sb.append(sources[remainder]);
    		}
    
    		return sb.reverse().toString();
    	}
    
    	/**
    	 * 列号转字母
    	 * 
    	 * @param columnIndex
    	 *            poi里xls的列号(从0开始)
    	 * @throws IllegalArgumentException
    	 *             if columnIndex less than 0
    	 * @return 该列对应的字母
    	 */
    	public static String getIndexLabel(int columnIndex) {
    		return getCorrespondingLabel(columnIndex + 1);
    	}
    
    }
    展开全文
  • JavaScript 转换数字为整数的方法

    万次阅读 2019-05-13 16:20:26
    本文将会列举并说明JavaScript 把一个number(或者numerical的对象)转换成一个整数相关方法。 使用parseInt parseInt的语法如下:parseInt(string, radix) 参数string的表示要解析的字符串,也可以是一个对象,会...

    本文将会列举并说明JavaScript 把一个number(或者numerical的对象)转换成一个整数相关方法。

    使用parseInt

    parseInt的语法如下:parseInt(string, radix)
    参数string的表示要解析的字符串,也可以是一个对象,会自动调用对象的toString函数得到要解析的字符串。

    parseInt的第二个参数,可以指定要解析的数字的基数,注意该值介于 2 ~ 36 之间,如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。比如下面的代码,结果为8,这样可以很方便的把其他的进制的数字转换为10进制的数字:

    parseInt(10,8) // 结果为8
    

    当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。
    举例,如果 string 以 "0x" 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。

    注释
    1. 只有字符串中的第一个数字会被返回。 什么意思呢,如果输入的字符串是"123abc","123,123",那么结果是123,parseInt方法会自动忽略后面的非数字部分。
    2. 输入字符串开头和结尾的空格是允许的。
    3. parseFloat 也具备以上两条特征,不过本文不重点讲述。

    使用Math.trunc

    Math.trunc() 方法会将数字的小数部分去掉,只保留整数部分。比如以下代码:

    Math.trunc(13.37)    // 13
    Math.trunc(42.84)    // 42
    Math.trunc(0.123)    //  0
    Math.trunc(-0.123)   // -0
    Math.trunc("-1.123") // -1
    Math.trunc(NaN)      // NaN
    Math.trunc("foo")    // NaN
    Math.trunc()         // NaN
    

    当传入的类型不是数字的时候,会自动做瘾式转换。但是如果是一个非numerical的参数的时候,返回NaN。
    IE浏览器并不支持这个方法,所以可以考虑polyfill:

    Math.trunc || (Math.trunc = function(v){
       return v < 0 ? Math.ceil(v) : Math.floor(v); // 使用Math.floor和Math.ceil方法
    })
    // 或者
    if (!Math.trunc) {
        Math.trunc = function(v) {
            v = +v;
            if (!isFinite(v)) return v;
            
            return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
            
            // 返回:
            //  0        ->  0
            // -0        -> -0
            //  0.2      ->  0
            // -0.2      -> -0
            //  0.7      ->  0
            // -0.7      -> -0
            //  Infinity ->  Infinity
            // -Infinity -> -Infinity
            //  NaN      ->  NaN
            //  null     ->  0
        };
    }
    

    二进制位运算

    对于numerical的对象n,可以通过如下的方式来转换为整数:

    • ~~n 双重位取反(Double bitwise NOT)
    • n | n 位或运算(Bitwise OR)
    • n | 0 和0的位或运算(Bitwise OR with 0)
    • n << 0 位左移运算0位(Bitwise left shift)
    • n >> 0 位右移运算0位(Bitwise right shift)
    • n & n 为与运算(Bitwise AND)
      比如代码如下:
       ~~1.23 // 1
       -1.2 | -1.2  // - 1
       -1.2 | 0  // - 1
       3.4 >> 0 // 3
       3.2 << 0 // 3
       5.5 & 5.5 // 5
      ~~"1.2" // 1.2 
    

    注意,从上面可以看出,位运算下字符串会自动转换数字。

    性能测试

    下面这个网址可以测试以上方法测性能情况,其中没有用到Math.trunc方法,用Math.floor方法代替了Math.trunc方法:
    https://jsperf.com/rounding-numbers-down

    我测试的结果如下,可以发现速度上,parseInt是最慢的,其他方法相对较快:

     

    性能测试

    性能测试

    从代码量的角度来说,n | 0 或则 ~~n是字符最少的,写起来应该也是最方便的, 但是可读性会变差。

    另外自己写代码测试了下Math.trunc和Math.floor的速度,比较结果如下:

        console.time('Math.trunc');
        for(var i = 0;i < 1000000000;i ++){
            Math.trunc(3.3);
        }
        console.timeEnd('Math.trunc');
    
        console.time('Math.floor');
        for(var i = 0;i < 1000000000;i ++){
            Math.floor(3.3);
        }
        console.timeEnd('Math.floor');
    //  Math.trunc: 8658.009033203125ms
    //  Math.floor: 7916.7890625ms
    

    位操作转换整数的原理

    参考Mozilla上面对于位操作的说明,点击下面链接:
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
    有这样一段话:

    Bitwise operators treat their operands as a sequence of 32 bits (zeroes and ones), rather than as decimal, hexadecimal, or octal [numbers]

    JavaScript中,数字存储是双进度64位浮点数。但是位操作却会把要操作的运算元当做32位带符号的整数。因此进行位操作时,会自动把数字先转换为整数。对数字n做前面提到的位运算,相当于n & 0xFFFFFFFF

    位运算优缺点

    用位操作进行整数转换的优点,大概包括如下:

    • 性能更快
    • 代码字符可以更少(比如 n | 0或者~~n)

    用位操作进行整数转换的缺点,大概包括如下:

    • 代码不易懂
    • 可能不能通过jsLint
    • 只支持32位以内的数据,超过范围就会得出错误的结果。

    对于“只支持32位以内的数据,超过范围就会得出错误的结果”这一点,因为位运算会把运算元当做32位带符号的整数,其范围是-2,147,483,648 到 2147483647 (0x7FFFFFFFF),超过范围就不奏效了。比如如下代码

    ~~2147483648.1//-2147483648
    

    由于2147483648.1超过了范围,其结果变成了-2147483648,而不是2147483648。下面列出安全和不安排的转换的更多示例:

     // Safe
     (2147483647.5918 & 0xFFFFFFFF) ===  2147483647
     (2147483647      & 0xFFFFFFFF) ===  2147483647
     (200.59082098    & 0xFFFFFFFF) ===  200
     (0X7FFFFFFF      & 0xFFFFFFFF) ===  0X7FFFFFFF
    
     // Unsafe
     (2147483648      & 0xFFFFFFFF) === -2147483648
     (-2147483649     & 0xFFFFFFFF) ===  2147483647
     (0x80000000      & 0xFFFFFFFF) === -2147483648
     (3000000000.5    & 0xFFFFFFFF) === -1294967296
    

    为了能够提高性能,又保证超过范围的时候安全可靠,可以考虑下面的polyfill:

    function trunc(n) {
        if (n > -0x80000000 && n < 0x80000000) {
          return n & 0xFFFFFFFF; //此处可以用 ~~n,n | 0等等
        }
        return Math.trunc(n);
    }
    

    Math.round 扩展

    同样可以用位操作实现Math.round的功能,比如:

    参考文档

    https://jsperf.com/rounding-numbers-down
    https://stackoverflow.com/questions/131406/what-is-the-best-method-to-convert-floating-point-to-an-integer-in-javascript
    https://j11y.io/javascript/double-bitwise-not/
    https://stackoverflow.com/questions/7487977/using-bitwise-or-0-to-floor-a-number
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
    https://jsperf.com/math-round-vs-hack/25

    欢迎关注公众号“ITman彪叔”。彪叔,拥有10多年开发经验,现任公司系统架构师、技术总监、技术培训师、职业规划师。熟悉Java、JavaScript。在计算机图形学、WebGL、前端可视化方面有深入研究。对程序员思维能力训练和培训、程序员职业规划和程序员理财投资有浓厚兴趣。

    ITman彪叔公众号

    ITman彪叔公众号

    展开全文
  • cat group-partition.log | awk -F ':' '$2>100{print $0}' 说明: -F 以什么分隔 $2代表第二 $2>100 代表第二大于100 print $0 代表输出一整行

    cat group-partition.log  | awk -F ':'  '$2>100{print $0}'

    说明:

    -F 以什么分隔列

    $2代表第二列

    $2>100 代表第二列大于100

    print $0 代表输出一整行

    展开全文
  • 2 方法概述 整个算法的流程见下表: 序号 步骤 1 图像的预处理 2 车牌粗定位 3 车牌精定位 4 车牌区域切割 5 字符切割 6 字符识别 2.1 图像的预处理 由于老师所给的数据集中
  • 先要出产品价格清单:产品代码、名称、对象类型、对象名称、价格,为此可以使用case根据obj_type进行取数来源切换,从而得到不同类型的obj_name,如下: select t0 . sid , t0 . goods_id , t1 . goods_no , ...
  • lodop 使用教程之图文详解 lodop 详细方法使用介绍 lodop 详细参数设置介绍
  • 1.随机填入1到4的数字到map,表示4种不同的宝石,格式化打印出地图内容,让地图内容肉眼可读。 【这道我写出来了,用的2个for循环】 2. 计算出符合条件的格子(横着或者竖着连续三个或三个以上相同)消除掉后的地图...
  • 结果一个K-邻近实现手写数字识别的代码就让我改了三四天。虽然网上这方面的代码是很多,但是我运行了好几个,结果都不是很理想。一次偶然的念想——为什么我不把这些代码的优点结合在一起呢,于是说做就做,年轻人嘛...
  • 身份证号码分为18位或15位数,如图 75‑1所示,之前使用15位数字,其中第15位数字为奇数表示男性,升级后以第17位数字的奇偶...下面与大家分享根据B18位或15位数的身份证号码判断性别男女的方法。 图75‑1 根据
  • js判断输入是否为数字、正整数、浮点数等的函数 <br /> 首先是判断是不是数字isNaN()var s = $(this).val(); if(isNaN(s)) {alert("不是数字");$(this).focus()} 1.下面出了一些判读数值...
  • ASCIISTR函数说明: ASCIISTR返回字符的ASCII形式的字符串。非ASCII的字符被转化为‘\xxxx’的形式。(xxxx为中文的ascii码) 使用ASCIISTR函数也是根据非ASCII字符会被转化这个特性来判别中文字符,只要里面...
  • Java反序化漏洞原理 谈起java反序化漏洞,相信很多人都不会陌生,这个在2015年首次被爆出的漏洞,几乎横扫了包括Weblogic、WebSphere、JBoss、Jenkins等在内的各大java web server,历经几年的发展变种,各种...
  • js如何判断输入是否为正整数、浮点数等数字的函数2007-12-19 15:44 1.下面出了一些判读数值类型的正则表达式 "^//d+$" //非负整数(正整数 + 0) "^[0-9]*[1-9][0-9]*$" //正整数 
  • 玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一、每一个同色九宫内的数字均含1-9,不重复。 数独的答案都是唯一的,所以,多个解也称为无解。 本图的数字据说是芬兰数学家花了3...
  • 基于FPGA的数字识别实现

    千次阅读 2019-07-21 17:30:34
    本篇博客就将介绍数字识别的方法,由于只是研究数字识别的方法,我们就不用硬件平台,而是用Modelsim和Matlab来仿真验证。 具体方法如下: 我们用画图软件将带有数字的图片截取为640x480像素,为了和我们将来要使用...
  • 数字电路设计之数字电路工程师面试集锦

    万次阅读 多人点赞 2014-11-07 22:43:29
    数字电路  1、同步电路和异步电路的区别是什么?(仕兰微电子)  2、什么是同步逻辑和异步逻辑?(汉王笔试)  同步逻辑是时钟之间有固定的因果关系。异步逻辑是各时钟之间没有固定的因果关系。  3、什么是...
  • 2、排除大写字母和数字 (?![A-Z0-9]+$) 3、排除大写字母和特殊字符 (?![A-Z\\W_!@#$%^&*`~()-+=]+$) 4、排除小写字母和数字 (?![a-z0-9]+$) 5、排除小写字母和特殊字符 (?![a-z\\W_!@#$%^&*`~()-+=]+$) 6、...
  • JS判断正整数、浮点数等方法

    千次阅读 2009-12-04 11:34:00
    1.下面出了一些判读数值类型的正则表达式 "^//d+$" //非负整数(正整数 + 0) "^[0-9]*[1-9][0-9]*$" //正整数 "^((-//d+)|(0+))$" //非正整数(负整数 + 0) "^-[0-9]*[1-9][0-9]*$" //负整数 "^-?...
  • Cocos2d-x-Lua 开发简单的小游戏(记数字踩白块) 本篇博客来给大家介绍如何使用Lua这门语言来开发一个简单的小游戏—记数字踩白块。 游戏的流程是这样的:在... 效果图如下: 先说明一下笔者的开发环境:Xcode 5.1
  • Matlab数字数字图像处理函数汇总

    千次阅读 2011-10-16 14:37:26
    Matlab数字数字图像处理函数汇总: 1、数字数字图像的变换 ① fft2:fft2函数用于数字数字图像的二维傅立叶变换,如:i=imread('104_8.tif'); j=fft2(i); ②ifft2::ifft2函数用于数字数字图像的二维傅立叶反...
  • 深入理解加密、解密、数字签名和数字证书  随着电子商务的迅速发展,信息安全已成为焦点问题之一,尤其是网上支付和网络银行对信息安全的要求显得更为突出。为了能在因特网上开展安全的电子商务活动,公开密钥...
  • 数字推理题的解题技巧

    千次阅读 2013-10-01 17:59:42
    本题典说明如下:本题典的所有题都适用! 1)题目部分用黑体字 2)解答部分用红体字 3)先给出的是题目,解答在题目后。 4)如果一个题目有多种思路,一并写出. 5)由于制作仓促,题目可能有错的
  • BP神经网络识别手写数字项目解析及代码

    万次阅读 多人点赞 2016-05-10 16:15:31
    这两天在学习人工神经网络,用传统神经网络结构做了一个识别手写数字的小项目作为练手。点滴收获与思考,想跟大家分享一下,欢迎指教,共同进步。 平常说的BP神经网络指传统的人工神经网络,相比于卷积神经网络(CNN...
  • 提出一种新方法用scratch编写游戏-数字华容道。该法仍然采用克隆法,每个克隆体有25个造型。所有克隆体不移动,用改变造型方法实现数字重新排列。
  • 数字 1-9 在每一只能出现一次。 3.数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 要弄清楚这个问题,就是要知道验证的算法是什么. 1.验证每一行上面是否出现了重复的数字...
  • 数字图像处理领域的二十四个典型算法及vc实现、第一章作者:July 二零一一年二月二十六日。参考:百度百科、维基百科、vc数字图像处理。--------------------------------------------------数字图像处理领域的二十...
  • 基于小波变换的数字水印技术

    万次阅读 2018-02-28 23:36:44
    1、数字水印介绍 现代许多应用与服务通过计算机网络提供,包括视频图像、电子数据交换等,然而网络在提供这些服务的同时却存在严重问题:数据作品的版权无法得到有效保护,有恶意的个人或团体可以在未得到版权所有...
  • 利用Tensorflow实现手写数字识别(附python代码)

    千次阅读 多人点赞 2019-08-22 16:00:22
    手写识别的应用场景有很多,智能手机、掌上电脑的信息工具的普及,手写文字输入,机器识别...我们来尝试搭建下手写识别中最基础的手写数字识别,与手写识别的不同是数字识别只需要识别0-9的数字,样本数据集也只需...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 151,432
精华内容 60,572
关键字:

如何判断列数字的说明方法