java中long最大值源码表示_通过JDK源码角度分析Long类详解

2023-11-18

概况

Java的Long类主要的作用就是对基本类型long进行封装,提供了一些处理long类型的方法,比如long到String类型的转换方法或String类型到long类型的转换方法,当然也包含与其他类型之间的转换方法。除此之外还有一些位相关的操作。

Java long数据类型

long数据类型是64位有符号的Java原始数据类型。当对整数的计算结果可能超出int数据类型的范围时使用。

long数据类型范围是-9,223,372,036,854,775,808至9,223,372,036,854,775,807(-2^63至2^63-1)。

long数据类型范围内的所有整数称为long类型的整数字面量。long类型的整数常数总是以大写L或小写l结尾。

以下是使用long类型的整数字面量的示例:

long num1 = 0L;

long num2 = 4L;

long mum3 = -3;

long num4 = 8;

long num5 = -1L;

本文主要介绍的是通过JDK源码分析Long类的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

继承结构

--java.lang.Object

--java.lang.Number

--java.lang.Long

主要属性

public static final long MIN_VALUE = 0x8000000000000000L;

public static final long MAX_VALUE = 0x7fffffffffffffffL;

public static final int BYTES = SIZE / Byte.SIZE;

public static final int SIZE = 64;

public static final Class TYPE = (Class) Class.getPrimitiveClass("long");

MIN_VALUE静态变量表示long能取的最小值,为-2的63次方,被final修饰说明不可变。

类似的还有MAX_VALUE,表示long最大值为2的63次方减1。

SIZE用来表示二进制补码形式的long值的比特数,值为64,静态变量且不可变。

BYTES用来表示二进制补码形式的long值的字节数,值为SIZE除于Byte.SIZE,结果为8。

TYPE的toString的值是long。

Class的getPrimitiveClass是一个native方法,在Class.c中有个Java_java_lang_Class_getPrimitiveClass方法与之对应,所以JVM层面会通过JVM_FindPrimitiveClass函数根据”long”字符串获得jclass,最终到Java层则为Class。

JNIEXPORT jclass JNICALL

Java_java_lang_Class_getPrimitiveClass(JNIEnv *env,

jclass cls,

jstring name)

{

const char *utfName;

jclass result;

if (name == NULL) {

JNU_ThrowNullPointerException(env, 0);

return NULL;

}

utfName = (*env)->GetStringUTFChars(env, name, 0);

if (utfName == 0)

return NULL;

result = JVM_FindPrimitiveClass(env, utfName);

(*env)->ReleaseStringUTFChars(env, name, utfName);

return result;

}

当TYPE执行toString时,逻辑如下,则其实是getName函数决定其值,getName通过native方法getName0从JVM层获取名称,

public String toString() {

return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))

+ getName();

}

getName0根据一个数组获得对应的名称,JVM根据Java层的Class可得到对应类型的数组下标,比如这里下标为11,则名称为”long”。

const char* type2name_tab[T_CONFLICT+1] = {

NULL, NULL, NULL, NULL,

"boolean",

"char",

"float",

"double",

"byte",

"short",

"int",

"long",

"object",

"array",

"void",

"*address*",

"*narrowoop*",

"*conflict*"

};

LongCache内部类

private static class LongCache {

private LongCache(){}

static final Long cache[] = new Long[-(-128) + 127 + 1];

static {

for(int i = 0; i < cache.length; i++)

cache[i] = new Long(i - 128);

}

}

LongCache是Long的一个内部类,它包含了long可能值的Long数组,默认范围是[-128,127],它不会像Byte类将所有可能值缓存起来,因为long类型范围很大,将它们全部缓存起来代价太高,而Byte类型就是从-128到127,一共才256个。这里默认只实例化256个Long对象,当Long的值范围在[-128,127]时则直接从缓存中获取对应的Long对象,不必重新实例化。这些缓存值都是静态且final的,避免重复的实例化和回收。

主要方法

parseLong方法

public static long parseLong(String s) throws NumberFormatException {

return parseLong(s, 10);

}

public static long parseLong(String s, int radix)

throws NumberFormatException

{

if (s == null) {

throw new NumberFormatException("null");

}

if (radix < Character.MIN_RADIX) {

throw new NumberFormatException("radix " + radix +

" less than Character.MIN_RADIX");

}

if (radix > Character.MAX_RADIX) {

throw new NumberFormatException("radix " + radix +

" greater than Character.MAX_RADIX");

}

long result = 0;

boolean negative = false;

int i = 0, len = s.length();

long limit = -Long.MAX_VALUE;

long multmin;

int digit;

if (len > 0) {

char firstChar = s.charAt(0);

if (firstChar < '0') { // Possible leading "+" or "-"

if (firstChar == '-') {

negative = true;

limit = Long.MIN_VALUE;

} else if (firstChar != '+')

throw NumberFormatException.forInputString(s);

if (len == 1) // Cannot have lone "+" or "-"

throw NumberFormatException.forInputString(s);

i++;

}

multmin = limit / radix;

while (i < len) {

// Accumulating negatively avoids surprises near MAX_VALUE

digit = Character.digit(s.charAt(i++),radix);

if (digit < 0) {

throw NumberFormatException.forInputString(s);

}

if (result < multmin) {

throw NumberFormatException.forInputString(s);

}

result *= radix;

if (result < limit + digit) {

throw NumberFormatException.forInputString(s);

}

result -= digit;

}

} else {

throw NumberFormatException.forInputString(s);

}

return negative ? result : -result;

}

两个parseLong方法,主要看第二个即可,第一个参数是待转换的字符串,第二个参数表示进制数。怎么更好理解这个参数呢?举个例子,Long.parseLong("100",10)表示十进制的100,所以值为100,而Long.parseLong("100",2)表示二进制的100,所以值为4。另外如果Long.parseLong("10000000000000000000",10)会抛出java.lang.NumberFormatException异常。

该方法的逻辑是首先判断字符串不为空且进制数在Character.MIN_RADIX和Character.MAX_RADIX之间,即2到36。然后判断输入的字符串的长度必须大于0,再根据第一个字符可能为数字或负号或正号进行处理。核心处理逻辑是字符串转换数字,n进制转成十进制办法基本大家都知道的了,假如357为8进制,则结果为$3*8^2+5*8^1+7*8^0 = 239$,假如357为十进制,则结果为$3*10^2+5*10^1+7*10^0 = 357$,上面的转换方法也差不多是根据此方法,只是稍微转变了思路,方式分别为$((3*8+5)*8+7) = 239$和$((3*10+5)*10+7)=357$。从中可以推出规则了,从左到右遍历字符串的每个字符,然后乘以进制数,再加上下一个字符,接着再乘以进制数,再加上下个字符,不断重复,直到最后一个字符。除此之外另外一个不同就是上面的转换不使用加法来做,全都转成负数来运算,其实可以看成是等价了,这个很好理解,而为什么要这么做就要归咎到long类型的范围了,因为负数Long.MIN_VALUE变化为正数时会导致数值溢出,所以全部都用负数来运算。

构造函数

public Long(String s) throws NumberFormatException {

this.value = parseLong(s, 10);

}

public Long(long value) {

this.value = value;

}

包含两种构造函数,分别可以传入long和String类型。它是通过调用parseLong方法进行转换的,所以转换逻辑与上面的parseLong方法一样。

static void getChars(long i, int index, char[] buf) {

long q;

int r;

int charPos = index;

char sign = 0;

if (i < 0) {

sign = '-';

i = -i;

}

while (i > Integer.MAX_VALUE) {

q = i / 100;

// really: r = i - (q * 100);

r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));

i = q;

buf[--charPos] = Integer.DigitOnes[r];

buf[--charPos] = Integer.DigitTens[r];

}

int q2;

int i2 = (int)i;

while (i2 >= 65536) {

q2 = i2 / 100;

r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));

i2 = q2;

buf[--charPos] = Integer.DigitOnes[r];

buf[--charPos] = Integer.DigitTens[r];

}

for (;;) {

q2 = (i2 * 52429) >>> (16+3);

r = i2 - ((q2 << 3) + (q2 << 1));

buf[--charPos] = Integer.digits[r];

i2 = q2;

if (i2 == 0) break;

}

if (sign != 0) {

buf[--charPos] = sign;

}

}

该方法主要做的事情是将某个long型数值放到char数组里面,比如把357按顺序放到char数组中。这里面处理用了较多技巧,将long拆成高位4个字节和低位4个字节处理分开处理,while (i >= Integer.MAX_VALUE)部分就是处理高位的4个字节,每次处理2位数,这里有个特殊的地方((q << 6) + (q << 5) + (q << 2))其实等于q*100,Integer.DigitTens和Integer.DigitOnes数组在前面Integer文章中已经讲过它的作用了,用来获取十位和个位。

接着看怎么处理低4个字节,它继续将4个字节分为高位2个字节和低位2个字节,while (i >= 65536)部分就是处理高位的两个字节,每次处理2位数,处理逻辑与高位4个字节的处理逻辑一样。

再看接下去的低位的两个字节怎么处理,其实本质也是求余思想,但又用了一些技巧,比如(i * 52429) >>> (16+3)其实约等于i/10,((q << 3) + (q << 1))其实等于q*10,然后再通过Integer.digits数组获取到对应的字符。可以看到低位处理时它尽量避开了除法,取而代之的是用乘法和右移来实现,可见除法是一个比较耗时的操作,比起乘法和移位。另外也可以看到能用移位和加法来实现乘法的地方也尽量不用乘法,这也说明乘法比起它们更加耗时。而高位处理时没有用移位是因为做乘法后可能会溢出。

toString方法

public static String toString(long i) {

if (i == Long.MIN_VALUE)

return "-9223372036854775808";

int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);

char[] buf = new char[size];

getChars(i, size, buf);

return new String(buf, true);

}

public String toString() {

return toString(value);

}

public static String toString(long i, int radix) {

if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)

radix = 10;

if (radix == 10)

return toString(i);

char[] buf = new char[65];

int charPos = 64;

boolean negative = (i < 0);

if (!negative) {

i = -i;

}

while (i <= -radix) {

buf[charPos--] = Integer.digits[(int)(-(i % radix))];

i = i / radix;

}

buf[charPos] = Integer.digits[(int)(-i)];

if (negative) {

buf[--charPos] = '-';

}

return new String(buf, charPos, (65 - charPos));

}

一共有3个toString方法,两个静态方法一个是非静态方法,第一个toString方法很简单,就是先用stringSize得到数字是多少位,再用getChars获取数字对应的char数组,最后返回一个String类型。第二个toString调用第一个toString,没啥好说。第三个toString方法是带了进制信息的,它会转换成对应进制的字符串。凡是不在2到36进制范围之间的都会被处理成10进制,我们都知道从十进制转成其他进制时就是不断地除于进制数得到余数,然后把余数反过来串起来就是最后结果,所以这里其实也是这样子做的,得到余数后通过digits数组获取到对应的字符,而且这里是用负数的形式来运算的。

valueOf方法

public static Long valueOf(long l) {

final int offset = 128;

if (l >= -128 && l <= 127) { // will cache

return LongCache.cache[(int)l + offset];

}

return new Long(l);

}

public static Long valueOf(String s) throws NumberFormatException

{

return Long.valueOf(parseLong(s, 10));

}

public static Long valueOf(String s, int radix) throws NumberFormatException {

return Long.valueOf(parseLong(s, radix));

}

有三个valueOf方法,核心逻辑在第一个valueOf方法中,因为LongCache缓存了[-128,127]值的Long对象,对于在范围内的直接从LongCache的数组中获取对应的Long对象即可,而在范围外的则需要重新实例化了。

decode方法

public static Long decode(String nm) throws NumberFormatException {

int radix = 10;

int index = 0;

boolean negative = false;

Long result;

if (nm.length() == 0)

throw new NumberFormatException("Zero length string");

char firstChar = nm.charAt(0);

if (firstChar == '-') {

negative = true;

index++;

} else if (firstChar == '+')

index++;

if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {

index += 2;

radix = 16;

}

else if (nm.startsWith("#", index)) {

index ++;

radix = 16;

}

else if (nm.startsWith("0", index) && nm.length() > 1 + index) {

index ++;

radix = 8;

}

if (nm.startsWith("-", index) || nm.startsWith("+", index))

throw new NumberFormatException("Sign character in wrong position");

try {

result = Long.valueOf(nm.substring(index), radix);

result = negative ? Long.valueOf(-result.longValue()) : result;

} catch (NumberFormatException e) {

String constant = negative ? ("-" + nm.substring(index))

: nm.substring(index);

result = Long.valueOf(constant, radix);

}

return result;

}

decode方法主要作用是解码字符串转成Long型,比如Long.decode("11")的结果为11;Long.decode("0x11")和Long.decode("#11")结果都为17,因为0x和#开头的会被处理成十六进制;Long.decode("011")结果为9,因为0开头会被处理成8进制。

xxxValue方法

public byte byteValue() {

return (byte)value;

}

public short shortValue() {

return (short)value;

}

public int intValue() {

return (int)value;

}

public long longValue() {

return value;

}

public float floatValue() {

return (float)value;

}

public double doubleValue() {

return (double)value;

}

包括shortValue、intValue、longValue、byteValue、floatValue和doubleValue等方法,其实就是转换成对应的类型。

hashCode方法

public int hashCode() {

return Long.hashCode(value);

}

public static int hashCode(long value) {

return (int)(value ^ (value >>> 32));

}

可以看到hashCode方法返回的事int类型,首先将long型值无符号右移32位,再和原来的值进行异或运算,最后返回int类型值。

hashCode方法

public boolean equals(Object obj) {

if (obj instanceof Long) {

return value == ((Long)obj).longValue();

}

return false;

}

比较是否相同时先判断是不是Long类型再比较值。

compare方法

public static int compare(long x, long y) {

return (x < y) ? -1 : ((x == y) ? 0 : 1);

}

x小于y则返回-1,相等则返回0,否则返回1。

无符号转换

private static BigInteger toUnsignedBigInteger(long i) {

if (i >= 0L)

return BigInteger.valueOf(i);

else {

int upper = (int) (i >>> 32);

int lower = (int) i;

return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).

add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));

}

}

public static String toUnsignedString(long i) {

return toUnsignedString(i, 10);

}

public static String toUnsignedString(long i, int radix) {

if (i >= 0)

return toString(i, radix);

else {

switch (radix) {

case 2:

return toBinaryString(i);

case 4:

return toUnsignedString0(i, 2);

case 8:

return toOctalString(i);

case 10:

long quot = (i >>> 1) / 5;

long rem = i - quot * 10;

return toString(quot) + rem;

case 16:

return toHexString(i);

case 32:

return toUnsignedString0(i, 5);

default:

return toUnsignedBigInteger(i).toString(radix);

}

}

}

toUnsignedBigInteger方法将long转成BigInteger类型,主要用BigInteger.valueOf进行转换,如果小于0则需要先转成高4字节和低4字节,然后再转换。

toUnsignedString方法中,对于大于0的long值直接用toString转换,而小于0的则要按照进制不同分别做不同处理。

bitCount方法

public static int bitCount(long i) {

// HD, Figure 5-14

i = i - ((i >>> 1) & 0x5555555555555555L);

i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L);

i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL;

i = i + (i >>> 8);

i = i + (i >>> 16);

i = i + (i >>> 32);

return (int)i & 0x7f;

}

该方法主要用于计算二进制数中1的个数。一看有点懵,都是移位和加减操作。先将重要的列出来,0x5555555555555555L等于0101010101010101010101010101010101010101010101010101010101010101,0x3333333333333333L等于0011001100110011001100110011001100110011001100110011001100110011,0x0f0f0f0f0f0f0f0fL等于0000111100001111000011110000111100001111000011110000111100001111。它的核心思想就是先每两位一组统计看有多少个1,比如10011111则每两位有1、1、2、2个1,记为01011010,然后再算每四位一组看有多少个1,而01011010则每四位有2、4个1,记为00100100,接着每8位一组就为00000110,接着16位,32位,64位,最终在与0x7f进行与运算,得到的数即为1的个数。

highestOneBit方法

public static long highestOneBit(long i) {

// HD, Figure 3-1

i |= (i >> 1);

i |= (i >> 2);

i |= (i >> 4);

i |= (i >> 8);

i |= (i >> 16);

i |= (i >> 32);

return i - (i >>> 1);

}

该方法返回i的二进制中最高位的1,其他全为0的值。比如i=10时,二进制即为1010,最高位的1,其他为0,则是1000。如果i=0,则返回0。如果i为负数则固定返回-2147483648,因为负数的最高位一定是1,即有1000,0000,0000,0000,0000,0000,0000,0000。这一堆移位操作是什么意思?其实也不难理解,将i右移一位再或操作,则最高位1的右边也为1了,接着再右移两位并或操作,则右边1+2=3位都为1了,接着1+2+4=7位都为1,直到1+2+4+8+16+32=63都为1,最后用i - (i >>> 1)自然得到最终结果。

lowestOneBit方法

public static long lowestOneBit(long i) {

return i & -i;

}

与highestOneBit方法对应,lowestOneBit获取最低位1,其他全为0的值。这个操作较简单,先取负数,这个过程需要对正数的i取反码然后再加1,得到的结果和i进行与操作,刚好就是最低位1其他为0的值了。

numberOfLeadingZeros方法

public static int numberOfLeadingZeros(long i) {

if (i == 0)

return 64;

int n = 1;

int x = (int)(i >>> 32);

if (x == 0) { n += 32; x = (int)i; }

if (x >>> 16 == 0) { n += 16; x <<= 16; }

if (x >>> 24 == 0) { n += 8; x <<= 8; }

if (x >>> 28 == 0) { n += 4; x <<= 4; }

if (x >>> 30 == 0) { n += 2; x <<= 2; }

n -= x >>> 31;

return n;

}

该方法返回i的二进制从头开始有多少个0。i为0的话则有64个0。这里处理其实是体现了二分查找思想的,先看高32位是否为0,是的话则至少有32个0,否则左移16位继续往下判断,接着右移24位看是不是为0,是的话则至少有16+8=24个0,以此类推,直到最后得到结果。

numberOfTrailingZeros方法

public static int numberOfTrailingZeros(long i) {

int x, y;

if (i == 0) return 64;

int n = 63;

y = (int)i; if (y != 0) { n = n -32; x = y; } else x = (int)(i>>>32);

y = x <<16; if (y != 0) { n = n -16; x = y; }

y = x << 8; if (y != 0) { n = n - 8; x = y; }

y = x << 4; if (y != 0) { n = n - 4; x = y; }

y = x << 2; if (y != 0) { n = n - 2; x = y; }

return n - ((x << 1) >>> 31);

}

与前面的numberOfLeadingZeros方法对应,该方法返回i的二进制从尾开始有多少个0。它的思想和前面的类似,也是基于二分查找思想,详细步骤不再赘述。

reverse方法

public static long reverse(long i) {

i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;

i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;

i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;

i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;

i = (i << 48) | ((i & 0xffff0000L) << 16) |

((i >>> 16) & 0xffff0000L) | (i >>> 48);

return i;

}

该方法即是将i进行反转,反转就是第1位与第64位对调,第二位与第63位对调,以此类推。它的核心思想是先将相邻两位进行对换,比如10100111对换01011011,接着再将相邻四位进行对换,对换后为10101101,接着将相邻八位进行对换,最后把64位中中间的32位对换,然后最高16位再和最低16位对换。

toHexString和toOctalString方法

public static String toHexString(long i) {

return toUnsignedString0(i, 4);

}

public static String toOctalString(long i) {

return toUnsignedString0(i, 3);

}

public static String toBinaryString(long i) {

return toUnsignedString0(i, 1);

}

static String toUnsignedString0(long val, int shift) {

int mag = Long.SIZE - Long.numberOfLeadingZeros(val);

int chars = Math.max(((mag + (shift - 1)) / shift), 1);

char[] buf = new char[chars];

formatUnsignedLong(val, shift, buf, 0, chars);

return new String(buf, true);

}

static int formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {

int charPos = len;

int radix = 1 << shift;

int mask = radix - 1;

do {

buf[offset + --charPos] = Integer.digits[((int) val) & mask];

val >>>= shift;

} while (val != 0 && charPos > 0);

return charPos;

}

这几个方法类似,合到一起讲。看名字就知道转成2进制、8进制和16进制的字符串。可以看到都是间接调用toUnsignedString0方法,该方法会先计算转换成对应进制需要的字符数,然后再通过formatUnsignedInt方法来填充字符数组,该方法做的事情就是使用进制之间的转换方法来获取对应的字符。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中long最大值源码表示_通过JDK源码角度分析Long类详解 的相关文章

  • JAVA的并发编程(八):Disruptor并发框架

    目录 一 Disruptor并发框架 1 介绍 2 关键知识点 3 实现方法 1 RingBuffer Disruptor 单线程 2 RingBuffer Squencebarrier BatchEventprocessor 多线程 单生
  • 杭电OJ 1002 A + B Problem II

    A B Problem II 页面数据来自 this page from http acm hdu edu cn showproblem php pid 1002 Time Limit 2000 1000 MS Java Others Me
  • linux EXPECT

    expect 概念 Expect除支持Unix Linux平台外 它还支持Windows平台 用过secureCRT的人应该知道有个自动登录的设置 那就是利用expect实现的 expect 安装需要那些包支持 tcl包和tk包 linux
  • Recovery系统升级(2)--- 软件架构

    软件架构 Recovery升级系统原理 Main System下载新版本升级包到设备存储 重启进入Recovery System Recovery从设备存储load升级包并升级Main System 最后重启回到Main System 与之
  • DLT(Diagnostic Log and Trace)嵌入式系统程序运行记录

    http blog csdn net yanlinembed article details 49837975 DLT的使用有属于Application范畴与Context范畴 在使用DLT时 需要包含以下头文件 include
  • 浅谈在线IDE的搭建,配置,体验

    首先想说一句 在线IDE体验不是很好 也可能是对于在线的IDE有了太多的期望 网页实现一些软件的功能确实比较困难 已经体验的IDE有 腾讯家的Coding Cloud Studio 亚马逊家的 Cloud9 代码沙盒 Codesandbox
  • 慧眼识才、认识自己

    慧眼识才的十二杆标尺 学历 经历 掌控特质 老虎性格 表现特质 孔雀性格 耐心特质 考拉性格 精确特质 猫头鹰性格 自信心 精力水平 现场爆发力 策略规划力 支持执行力 敏锐度 慧眼识才的十二杆标尺包括由表及里的五个圈层 最外层是学历和经历
  • maven [INFO] Generating project in Batch mode

    搜资料很简单是某些东西被Q了 那么解决方法也很简单 S S T A P全局模式就OK了
  • Flask框架的web开发02(web项目整体架构)

    目录 一 flask框架整体构造 1 介绍 2 构造图 二 核心对象 管理 启动模块 1 核心对象app py模块 2 管理模块manager py 3 启动模块server py 三 配置文件模块 四 forms验证模块 五 libs公共
  • 关于华三HCL使用时,设备端口状态为down的解决

    内存不能低于默认值 可以通过关闭一些模拟器中的设备 可以关闭物理机上一些正在使用的应用和后台程序 一台或少量的启动设备
  • 习题

    1 在路由器上配置SSH服务器的过程 2 简述以太网交换机Mac地址表的学习过程 首先当4台pc机连接到交换机相互通信时 交换机会取出每个数据包的源MAC地址 通过算法找到相应的位置 如果是新地址 则创建地址表项 填写相应的端口信息 生命周
  • 1132. 合法的三角数

    给定一个包含非负整数的数组 你的任务是计算从数组中选出的可以制作三角形的三元组数目 如果我们把它们作为三角形的边长 样例 输入 2 2 3 4 输出 3 解释 合法的组合如下 2 3 4 使用第一个 2 2 3 4 使用第二个 2 2 2
  • 【机试练习】【C++】随机选择算法

    随机选择算法的实现 include
  • 【并发多线程】java.util.concurrent简介

    主要的组件 Executor ExecutorService ScheduledExecutorService Future CountDownLatch CyclicBarrier Semaphore ThreadFactory java
  • matlab遗传算法求多元函数最小值,matlab遗传算法求函数最小值

    function obj yichuan lb ub px pm lb ub为自变量的下界与上界 px为杂交概率 pm为变异概率 popsize 40 设定种群大小为40 maxgen 500 设定最大遗传代数为500代 dim 20 定义
  • 鸡和兔子共36脚100Matlab,matlab编程.ppt

    matlab编程 ppt 由会员分享 可在线阅读 更多相关 matlab编程 ppt 51页珍藏版 请在人人文库网上搜索 1 1 Matlab 编程基础 数学实验 数学软件 Matlab 2 本讲主要内容 M 文件 Matlab 编程基础
  • c语言基础回顾 —— 其他知识点

    参考 c语言基础回顾 其他知识点 作者 丶PURSUING 发布时间 2021 03 11 14 48 59 网址 https blog csdn net weixin 44742824 article details 114666007
  • python实现微信机器人: 登录微信、消息接收、自动回复

    安装wxpy pip install U wxpy 登录微信 导入模块 from wxpy import 初始化机器人 扫码登陆 bot Bot 运行以上代码 会生成一个二维码 通过图片扫描二维码即可登录微信 如果是在服务器上运行代码 无法
  • 了解java

    目录 一 Java是什么 二 Java语言特性 1 简单性 2 面向对象 3 健壮性 4 多线程 5 可移植性 跨平台 三 Java两种核心机制 1 Java虚拟机 Java Virtal Machine 2 垃圾收集机制 Garbage

随机推荐

  • 【22-23 春学期】人工智能基础--AI作业10-经典卷积网络

    LeNet MNIST LeNet是由Yann LeCun及其合作者于1998年开发的一种具有开创性的卷积神经网络架构 它的设计目的是识别手写数字并执行图像分类任务 MNIST是一个用于手写数字识别的大型数据库 常被用于训练图像处理系统 L
  • VTK C++版本本地编译(含OOCT编译及创建项目)

    官方编译 以Linux为主 也有Window的处理方式 可以参考 讲述Windows环境下如何进行处理 前期准备 VTK ZIP 建议下载最新版 否则会出错 也可按照需要自行选择 CMake Visualstudio 版本无要求 我下载的是
  • [仿真]PMSM矢量控制——滑模速度环

    PMSM在Simulink下的FOC滑模速度环仿真 摘要 PMSM的FOC模型 PI速度环 PMSM的FOC模型 滑模速度环 关于滑模速度环改进的讨论 摘要 本文将通过一个PMSM在Simulink下的FOC仿真 来对比PI速度环和滑模速度
  • echarts地图的常见用法:基本使用、区域颜色分级、水波动画、区域轮播、给地图添加背景图片和图标、3d地图、飞线图

    前言 最近几天用echarts做中国地图 就把以前写的demo 在vue中实现中国地图 拿来用 结果到项目里直接报错了 后来发现是因为版本的问题 没办法只能从头进行踩坑了 以下内容基于vue3 和 echarts 5 32 常用的功能应该就
  • 在Unity中使用暂停的小技巧

    很多人在游戏中写暂停脚本的时候 经常会想到 Time timeScale 0 这种方法 但是 Time timeScale 只是能暂停部分东西 如果在 update 函数中持续改变一个物体的位置 这种位置改变貌似是不会受到暂停影响的 比如
  • pcl make failed - libSM.so:

    usr lib x86 64 linux gnu libSM so undefined reference to uuid generate UUID 1 0 usr lib x86 64 linux gnu libSM so undefi
  • php 接收及发送POST/GET请求 接收Xml格式数据POST请求及发送

    补充三点说明 1 Get请求数据根据索引关键字直接从全局变量 GET中获取 无需再调用urldecode解码 GET 数组 存储Get请求字符串 用 划分字符串为数组 数组元素的形式为 a b 2 POST请求字符串形式的数据同样可以根据索
  • SqlServer2008如何解析Json—附详细代码

    1 在数据库中创建存储过程parseJSON 具体文件请在如下链接下载 链接 https pan baidu com s 1a aNmSKk yvv9wQTP3DCsg pwd yxwx 提取码 yxwx 2 具体使用方法如下 DECLAR
  • jeckins安装以及构建github上的项目

    1 安装Jenkins 下载地址 http jenkins ci org 选择Windows的native package进行下载 安装过程与所有的windows安装程序一样 简单和傻瓜 不说了 安装完成之后会自动创建一个windows服务
  • VMware安装Windows Server 2003提示Operating System not found

    VMware安装Windows Server 2003提示Operating System not found 解决方法 首先 检查虚拟机设置里的设备状态的启动时连接是不是没勾选 还是不行的话 换一个ISO文件 正常的文件大小是600多兆
  • EMQ关闭MQTT客户端匿名认证

    本文默认已经安装并且开启emqttd 做的事是关闭MQTT客户端匿名认证并且通过username和passward认证 且有一定的Linux命令基础 环境 Ubuntu16 04 emq v3 2 1 正文 关闭匿名认证 emq安装时 默认
  • MATLAB数据预处理之缺失值插补

    文章目录 前言 1 加载原始数据 2 查找缺失值并填充缺失值 总结 2021年4月5日09 51 56更新 2021年5月18日10 46 15更新 2022年10月15日07 25 01更新 参考资料 前言 现实中采集的原始数据不一定满足
  • Apache HTTP Server 2.4.49 路径穿越漏洞复现及利用

    漏洞介绍 Apache HTTP Server是Apache基金会开源的一款流行的HTTP服务器 在其2 4 49版本中 引入了一个路径穿越漏洞 满足下面两个条件的Apache服务器将会受到影响 版本等于2 4 49 穿越的目录允许被访问
  • html任务3 模拟滚动条,vue3系列:vue3.0自定义虚拟滚动条V3Scroll

    Desc Vue3 0虚拟滚动条组件V3Scroll Time andy by 2021 01 About Q 282310962 wx xy190310 props Vue3 x自定义指令写法 监听DOM尺寸变化 directives r
  • 微信小程序之基础指南

    目录 1 申请账号 2 微信开发者工具 3 小程序代码构成 3 1 JSON配置 3 1 1 小程序全局配置app json 3 1 2 小程序页面配置 3 1 3 sitemap 配置 4 小程序框架 4 1 场景值 4 2 注册小程序
  • 探密微信小程序开发中的OpenlD

    说到微信小程序开发 我们不得不提到原生系统中自带的OPENiD 用户在跟公众号交互时 为了让程序识别用户的身份 需要有一个身份标识 出于对用户信息安全的考虑 保护用户隐私 微信没有暴露用户的微信号 而是对开发者提供OpenlD 它是一个由数
  • 数学建模(三)—— 自动化车床管理

    一 题目要求 二 相关的基础知识 2 1 正态分布的假设检验 2 2 正态分布的概率 三 问题分析 四 模型的建立与求解 4 1 数据处理及分析 4 2 问题一模型的建立与求解 4 2 1 问题一模型的建立 4 2 2 问题一模型的求解 4
  • 面试复习题--音视频

    1 音频处理 oboe openSL es AAudio 2 视频处理 ffmpeg 3 图片处理 GPUImage OpenCV fastCV 4 图形基础 skia Vulkan
  • 匿名信V1.4.5.1版本更新“数据大屏”功能

    匿名信V1 4 5 1版本更新 数据大屏 功能 源码下载 匿名信h5源码 万策云盘 匿名信安装教程 匿名信v1 4 4源码下载 安装教程 匿名信 廖万里的博客 本文链接 匿名信V1 4 5 1版本更新 数据大屏 功能 匿名信 廖万里的博客
  • java中long最大值源码表示_通过JDK源码角度分析Long类详解

    概况 Java的Long类主要的作用就是对基本类型long进行封装 提供了一些处理long类型的方法 比如long到String类型的转换方法或String类型到long类型的转换方法 当然也包含与其他类型之间的转换方法 除此之外还有一些位