1、有没有人尝试过将负数赋给一个无符号整型变量?知不知道这样做会发生什么?还没有尝试的就让我们来探索下无符号整型隐藏的秘密。
先来看看下面代码:
int main() return 0; 执行的结果: 4294967295 ---------------------------------------- 你可能禁不住惊叹:这么大!没想到吧,把一个负数赋值给无符号整型变量,会产生这么大的数!为啥呢?好,我们一步步分析: 首先,仔细观察输出的结果4294967295,发现4294967295=2^32-1,哦!好像有点规律!但是,又为啥会是这样?让我们先来讨论下int和unsigned int的表现形式,其中他俩都是4个字节,32位的二进制表示,但int有一位是符号位,unsigned则没有。那-1的int类型表示为1000 0000 0000 0000 0000 0000 0000 0001,那么将其强制转换成unsigned int 应该是1000 0000 0000 0000 0000 0000 0000 0001(红色为符号位),用指数表示是2^31+1,而不是2^32-1!这是怎么回事呢?(*^__^*) 嘻嘻……,这里还隐藏着一个小秘密!那就是int在真正存储在内存中的二进制数不是值的原码,而是其补码(为了便于运算,可以参考《数字逻辑》)!那么在强制类型转换之前,int变量-1内存中存储的是1111 1111 1111 1111 1111 1111 1111 1111,等于2^32-1。soso在强转为unsigned int时,就是读取该块内存的值赋给变量!这样val就变成了4294967295,超级大的数!所以各位同仁在处理unsigned int 赋值时一定要谨慎!如果出错将影响甚大,因为unsigned int一般都会作为for或while循环体的标识类型,如果将负值赋给它,将导致严重的假死循环!痛哉!痛哉! 2、负数的补码:负数的补码是对其原码逐位取反,但符号位除外;然后整个数加1。 同一个数字在不同的补码表示形式里头,是不同的。比方说-15的补码,在8位2进制里头是11110001,然而在16位2进制补码表示的情况下,就成了1111111111110001。在这篇补码概述里头涉及的补码转换默认把一个数转换成8位2进制的补码形式,每一种补码表示形式都只能表示有限的数字。
【例2】求-7的补码。 因为给定数是负数,则符号位为“1”。取反加一 后七位:-7的原码(10000111)→按位取反(11111000)(负数符号位不变)→加1(11111001) 所以-7的补码是11111001。 3、正数的补码:正数的补码是其原身。
与原码相同。 【例1】+9的补码是00001001。(备注:这个+9的补码说的是用8位的2进制来表示补码的,补码表示方式很多,还有16位2进制补码表示形式,以及32位2进制补码表示形式等。) 4、对相同符号的不同类型的数据进行赋值,则不会出现数据变化的情况, 例如: 其正确的读取方法是:
{
unsigned int val = -1;
cout<
}
请按任意键继续. . .
6、虽然上面的进行相同符号的取值赋值时不会出现错误,但是opencv如果是不同数据类型进行操作的话则会出现错误,有的是不会报错,但数据不对。
int hh = 0;
hh = (double)-818.626381968738; //hh结果是-818,其是舍弃后面的,而不会进行几舍几入运算的。
Mat camera_matrix = Mat(3, 3, CV_64FC1, camD); //定义的图像是64位的double型
Mat distortion_coefficients = Mat(5, 1, CV_64FC1, distCoeffD);
if (first == false){
first = true;
cvSave("Intrinsics.xml", &CvMat(camera_matrix));
cvSave("rotation.xml", &CvMat(rotM));
cvSave("translation.xml", &CvMat(tvchange));
}
float fx=0, fy=0, cx=0, cy=0, k1, k2, p1, p2, k3; //define intrinsic, distortion_coeff
float r11, r12, r13, r21, r22, r23, r31, r32, r33; //rotation matrix
float t1, t2, t3;
CvMat *intrinsic_matrix = (CvMat*)cvLoad("Intrinsics.xml");
CvMat *rotation_mat_final = (CvMat*)cvLoad("rotation.xml");
CvMat *translation_vector = (CvMat*)cvLoad("translation.xml");
fx = CV_MAT_ELEM(*intrinsic_matrix, float, 0, 0); //读取的值是错误的,但是程序不会报错,其是由于数据类型跟存储的不同一个是double,一个是float。
fy = CV_MAT_ELEM(*intrinsic_matrix, double, 1, 1); //读取的值是正确的。
cx = CV_MAT_ELEM(*intrinsic_matrix, double, 0, 2);
cy = CV_MAT_ELEM(*intrinsic_matrix, double, 1, 2);
float hh = 0;
hh = (double)-818.626381968738; //但是这个直接赋值的却是正确的,其hh为-818.626381被舍弃了一些数据位。