#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
typedef unsigned char* byte_pointer;
//输入为一个字节序列的地址(起始位置),用一个字节指针和一个字节数来表示,输出为字节表示,每个地址中的值
void show_bytes(byte_pointer start, size_t len)
{
size_t i;//size_t是unsigned int的别名,在头文件中已经定义
for (i = 0; i < len; i++)
printf("%.2x", start[i]);//十六进制格式输出
printf("\n");
}
int main()
{
int a = 1;
byte_pointer b = (byte_pointer)&a;
show_bytes(b,sizeof(byte_pointer));//01000000cccccccc
show_bytes(b, sizeof(short));//0100
show_bytes(b, sizeof(long long ));//01000000cccccccc
}
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
typedef unsigned char* byte_pointer;
//输入为一个字节序列的地址(起始位置),用一个字节指针和一个字节数来表示,输出为字节表示,每个地址中的值
void show_bytes(byte_pointer start, size_t len)
{
size_t i;//size_t是unsigned int的别名,在头文件中已经定义
for (i = 0; i < len; i++)
printf("%.2x", start[i]);//十六进制格式输出
printf("\n");
}
void show_short(short x)
{
show_bytes((byte_pointer)&x, sizeof(short));
}
void show_double(double x)
{
show_bytes((byte_pointer)&x, sizeof(double));
}
void show_long(long x)
{
show_bytes((byte_pointer)&x, sizeof(long));
}
int main()
{
show_short(11);//0b00
show_double(11);//0000000000002640
show_long(11);//0b000000
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int is_little_endian()
{
int i = 1;
char c = (*(char*)&i);
if (c)
{
printf("小端\n");
return 0;
}
else
{
return 1;
printf("大端\n");
}
}
int main()
{
int a = is_little_endian();
return 0;
}
//定义变量int i=1;将 i 的地址拿到,强转成char*型,这时候就取到了 i 的低地址,
//这时候如果是1就是小端存储,如果是0就是大端存储。
//大端,是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中
//小端,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int combine(int a, int b)
{
a = 0xff & a;
b = (~0xff) & b;
return a + b;
}
int main()
{
int a = 0x12345678;
int b = 0x11111111;
int c = combine(a, b);
printf("%x", c);//11111178
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
unsigned replace_byte(unsigned x, int i, unsigned char b)
{
int temp = 0xff;
temp = temp & b;
temp = temp << i*8;
printf("%x \n", temp);
int tempx = 0xff << i * 8;//一个字节有8位,unsigned char的大小位一个字节
x = x & (~tempx);
printf("%x\n", x);
return temp | x;
}
int main()
{
unsigned a = 0x12345678;
unsigned char b = 0xAB;
unsigned c = replace_byte(a, 2, b);
printf("%x", c);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
int judge(int x)
{
return (!~x) || (!x) || (!~(x | 0xffffff00)) || (!~(x | 0x00ffffff));
}
int main()
{
return judge(0x00000010);
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int int_shifts_are_arithmetic()
{
int x = ~0x01;
x = x >> 4;//0xffffffff(算数右移)0x0fffffff(逻辑右移)
printf("%x\n", x);
return !(~x);
}
int main()
{
return int_shifts_are_arithmetic();
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
unsigned srl(unsigned x,int k)
{
unsigned xsra = (int)x >> k;//算术右移
int w = sizeof(int)<<3;//位数(<<3相当于乘以8)
unsigned mask = ~(((1 << k) - 1) << (w - k));//((1 << k) - 1) 能获得低位连续为1,高位为0,有k个1,(w-k)使得前k个高位为1,取反则可使前k为0
return xsra & mask;
}
int sra(int x, int k)
{
int xsrl = (unsigned)x >> k;//逻辑右移
int w = sizeof(int) << 3;
int test = 1 << (w - k - 1);
int mask = test & xsrl;
mask = ~(mask - 1);
return mask | xsrl;
}
int any_odd_one(unsigned x) {
unsigned int t = 0x55555555;//0x01010101010101010101010101010101
return (x & t) != 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int odd_ones(unsigned x)
{
x ^= x >> 1;
x ^= x >> 2;
x ^= x >> 4;
x ^= x >> 8;
x ^= x >> 16;/最后一位将所有位数的1进行计数
return x & 1;
}
int main()
{
int a = odd_ones(0xffff1010);//0
printf("%x", a);
int b = odd_ones(0x1110ffff);//1
printf("%x", b);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
int leftmost_one(unsigned x)
{
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;//结果是x(32)x(3231)x(323130)...x(32...1)
return x ^ (x >> 1);
}
int bad_int_size_is_32()
{
int set_msb = 1 << 31;
//int beyond_msb = 1 << 32;
//当移位数过大时,有的编译器会进行取模操作,有的则不会,故代码不是通用的
int beyond_msb = set_msb;
beyond_msb <<= 1;
return set_msb && !beyond_msb;//非零的数都是逻辑真,!是逻辑运算不是取反
}
int int_size_is_32()
{
int set_msb = 1 << 15;
set_msb <<= 15;
set_msb <<= 1;
int beyond_msb = set_msb;
beyond_msb <<= 1;
return set_msb && !beyond_msb;
}
int lower_one_mask(int n)
{
int sizeof_int = sizeof(int);
unsigned x = ~0;//0xffffffff
x >>= ((sizeof_int << 3) - n);
return x;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
unsigned rotate_left(unsigned x, int n)
{
int w = sizeof(unsigned) << 3;
unsigned lower = x >> (w - n);
unsigned higher = x << n;
return lower | higher;
}
int main()
{
unsigned a = rotate_left(0x12345678, 4);
printf("%x\n", a);
unsigned b = rotate_left(0x12345678, 20);
printf("%x\n", b);
return 0;
}
//x用n位表示
int fits_bits(int x,int n)
{
unsigned sizeof_int = sizeof(int);
unsigned w = sizeof_int << 3;
int y = x << (w-n) >> (w-n);
return y == x;
}
#define _CRT_SECURE_NO_WARNINGS 1
typedef unsigned packed_t;
int xbyte(packed_t word, int bytenum)
{
//return (word >> (bytenum << 3)) & 0xff;
//原来代码的问题是在所抽出的字节是负数的情况下得到是无符号数而不是有符号数
// 当取出的字节为负数时,由于原操作“粗暴”的将高位置零,会返回一个错误的正值。
//程序比要求的多了一个强制类型转换因为要求的是在算术右移的机器上运行而一般机器是对于无符号逻辑右移
unsigned left_move = (3 - bytenum) << 3;
unsigned right_move = (3) << 3;
return (int)word << left_move >> right_move;
}
#define _CRT_SECURE_NO_WARNINGS 1
void copy_int(int val,void *buf,int maxtybes)
{
//if (maxtybes-sizeof(val) >= 0)
// size_t is an unsigned integer type
//maxbytes-sizeof(val)将一直转化为无符号数并永远大于等于零
if (maxtybes < 0)
return;
if(maxtybes>=sizeof(val))
memcpy(buf, (void*)&val, sizeof(val));
}
int saturating_add(int x, int y)
{
unsigned sizeof_int = sizeof(int);
int bias = (sizeof(int) << 3) - 1;/
int i = (x ^ y )>> bias;//比较符合位是否相同
int j = ((x+y) ^ x) >> bias;//是否相加后变符号,是否溢出
int k = x >> bias;//判断正溢出还是负溢出
return (i & (x + y)) + (~i & (j & ( (~k & INT_MAX) + (k & INT_MIN) )));
}
#define _CRT_SECURE_NO_WARNINGS 1
int tsub_ok(int x,int y)
{
y = -y;
unsigned sizeof_int = sizeof(int);
int bias = sizeof_int << 3 - 1;
int i = (x ^ y) >> bias;
int j= ((x + y) ^ x) >> bias;
return i || ~j;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <stdint.h>
#include <stdbool.h>
unsigned unsigned_high_prod(unsigned x, unsigned y)
{
unsigned w = sizeof(int32_t) << 3;
int64_t signed_total_prod = signed_high_prod(x, y);
signed_total_prod <<= w;
signed_total_prod += x * y;
bool x_w = x < 0 ? true : false;
bool y_w = y < 0 ? true : false;
int64_t unsigned_total_prod = signed_total_prod + ((x_w * (int)y + y_w * (int)x) << w) + x_w * y_w << (w * 2);
return (unsigned)(unsigned_total_prod >> w);
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stddef.h>
typedef unsigned size_t;
void* Calloc(size_t nmemb, size_t size) {
if (nmemb == 0 || size == 0) return NULL;
int s = nmemb * size;
if (s / size == nmemb) { //检测溢出
void* p = malloc(s);
memset(p, 0, s);
return p;
}
return NULL;
}
#define _CRT_SECURE_NO_WARNINGS 1
int K_multiply(int x,int K)
{
if (K == 17)
x = x << 4 + x;
else if (K == -7)
x = -(x << 3 - x);
else if (K == 60)
x = x << 6 - x << 2;
else if (K == -112)
x = -x << 7 + x << 4;
return x;
}
#define _CRT_SECURE_NO_WARNINGS 1
int divide_power2(int x, int k)
{
return (x > 0 ? x + (1 << k) - 1 : x) >> k;
}
int mul3div4(int x)
{
int k = 2;
int bias = (1 << k) - 1;//3
unsigned sizeof_int = sizeof(int);
unsigned w = sizeof_int << 3;
x = (x << 1) + x;//没有考虑溢出
int judge = x >> (w - 1); //判断正负
return (judge & ((x + bias) >> k)) + (~judge & (x >> k));
}
#include<stdio.h>
int threefourthd(int x)
{
int k = 2;
int bias = (1 << k) - 1;
unsigned sizeof_int = sizeof(int);
unsigned w = sizeof_int << 3;
int judge = x >> (w - 1); //-:FFFFFFFF +:00000000
x = (x << 1) + x;
//如果先除容易变成0,但是先乘容易溢出
return (judge & ((x + bias) >> k)) + (~judge & (x >> k));
}
int main()
{
int a = threefourthd(3);
printf("%d\n", a);
int b = threefourthd(-1);
printf("%d\n", b);
return 0;
}
unsigned only_k(unsigned k)
{
unsigned w = sizeof(unsigned) << 3;
unsigned a = ~0;
return a << k;
}
unsigned k_j(unsigned k, unsigned j)
{
unsigned w = sizeof(unsigned) << 3;
unsigned a = ~0;
a = a << (w-k);
return a >> (w-j-k);
}
A:当x是最小值时,其负数还是最小值
B:1,LEFT = ((((((x+y)mod)16)mod)+y)mod)-x)mod = (17y + 15x)mod. RIGHT = (17y)mod + (15x)mod = (17y + 15x)mod.
C:1, LEFT = (~x + 1) + (~y + 1) - 1 = -x + -y - 1. RIGHT = ~(x+y) + 1 - 1 = -(x+y) - 1 = -x + -y - 1.
D:1
E:1
Y = x2k - x 即 x = Y/(2k- 1)
(a) Y = 101 = 5, k = 3, x = 5/7 (b) Y = 0110 = 6, k = 4, x = 2/5 © Y = 010011 = 19, k = 6, x = 19/63
return (sx ^ sy) ? (sx ? 1 : 0): (sx ? (ux>=uy) : (ux<=uy));
V=(-1)s×M×2E
Bias=2k-1-1
E=e-Bias
M=1+f
A:7.0=111=1.11210(二进制)
M=1.11,E=10,f=0.1100…
e=10+Bias
(-1)s1011000…
B:E = n+bias, M = 0b1.11, f = 0b11*, V = 2^(n+1)-1
0, n+bias, 11*
C: E = 0b001, M = 0b1.00, f = 0b00*, V = 1.0
0 00…00 00…01 2-63*2^ (-214-1)
0 00…01 00…00 2 ^ (-214-1)
0 11…10 11…11 (2-2(-63)) * (2(14)-1)
| 8000 | 0 | -14 | 0 | 0 |
| 4001 | 1025/1024 | 1 | 10252^-8 | 2.001953 |
| 512 | 6000 | 1 | 9 | 12^9 | 512.000000 |
| 1023/1024 | -14 | 10232^-24 | 0.000061 |
| - | - | - | -inf |
| 3BB0 | 124/64 | -1 | 312^-5 | 0.968750 |
| Format A | Format A | Format B | Format B |
| Bits | Value | Bits | Value |
| 1 01111 001 | -9/8 | 1 0111 0010 | -9/8 |
| 0 10110 011 | 1124 | 0 1110 0110 | 1124 |
| 1 00111 010 | -52-10 | 1 0000 0101 | -52-10 |
| 0 00000 111 | 72-17| 0 0000 0001 | 2-10 |
| 1 11100 000 | -213 | 1 1110 1111 | -3123 |
| 0 10111 100 | 327 | 0 1110 1111 | 3123 |
A:1
B:不总是返回1.如x=INT_MIN,Y=1
C:1
D:不总是返回1.例如dx与dy互为倒数且dy*dz=+infinite
E:不总是返回1.例如dx=1.0, dz=0.0
float fpwr2(int x)
{
/* Result exponent and fraction */
unsigned exp, frac;
unsigned u;
if (x < -149)// 小于最小的非规格化数
{
/* Too small. Return 0.0 */
exp = 0;
frac = 0;
}
else if (x < -126) // 非规格化数
{
/* Denormalized result */
exp = 0;
frac = 1 << (149 + x);
}
else if (x < 128) // 规格化数
{
/* Normalized result. */
exp = x + 127;
frac = 0;
}
else// 大于最大规格化数
{
/* Too big. Return +oo */
exp = 0xFF;
frac = 0;
}
/*Pack exp and frac into,32 bits */
u = exp << 23 | frac;
/* Return as float */
return u2f(u);
}
0x 40490FDB = 0b 0100 0000 0100 1001 0000 1111 1101 1011 = 0,10000000,10010010000111111011011
A: 10010010000111111011011
B: y=1, k=3, 即 0b11.(001)*
C: 0x4049039b 0x40492492 从高位向低位第19个。
#include <stdio.h>
typedef unsigned float_bits;
float_bits float_negate(float_bits f) {
unsigned sign = f >> 31;
unsigned exp = f >> 23 & 0xFF;
unsigned frac = f & 0x7FFFFF;
int is_NAN = (exp == 0xFF) && (frac != 0);
if (is_NAN) {
return f;
}
return ~sign << 31 | exp << 23 | frac;
}
typedef unsigned float_bits;
float_bits float_absval(float_bits s)
{
unsigned sign = s >> 31;
unsigned exp = s >> 23 & 0xFF;
unsigned frac = s & 0x7FFFFF;
int is_NAN = (exp == 0xFF) && (frac != 0);
if (is_NAN) {
return s;
}
return 0 << 31 | exp << 23 | frac;
}
typedef unsigned float_bits;
float_bits float_twice(float_bits f)
{
unsigned sign = f >> 31;
unsigned exp = f >> 23 & 0xFF;
unsigned frac = f & 0x7FFFFF;
int is_NAN = (exp == 0xFF) && (frac != 0);
if (is_NAN) {
return f;
}
if (exp == 0) //非规格化数
frac <<= 1;
else if (exp == 0xFF - 1) { //*2后为无穷
exp = 0xFF;
frac = 0;
}
else //规格化数
exp += 1;
return sign << 31 | exp << 23 | frac;
}
#include <stdio.h>
typedef unsigned float_bits;
float_bits float_half(float_bits f) {
unsigned sign = f >> 31;
unsigned exp = f >> 23 & 0xFF;
unsigned frac = f & 0x7FFFFF;
unsigned rest = f & 0x7FFFFFFF;
if (exp == 0xFF) { //如果f为NAN或无穷,直接返回
return f;
}
int addition = (frac & 0x3) == 0x3; //向偶数舍入偏置
if (exp == 0) { //非规格化数,<<1后加偏置
frac >>= 1;
frac += addition;
}
else if (exp == 1) { //规格化数变为非规格化数
rest >>= 1;
rest += addition;
exp = rest >> 23 & 0xFF;
frac = rest & 0x7FFFFF;
}
else { //规格化数
exp -= 1;
}
return sign << 31 | exp << 23 | frac;
}
#include <stdio.h>
typedef unsigned float_bits;
int float_f2i(float_bits f) {
unsigned sign = f >> 31;
unsigned exp = f >> 23 & 0xFF;
unsigned frac = f & 0x7FFFFF;
unsigned bias = 0x7F;
int num;
unsigned E;
unsigned M;
if (exp >= 0 && exp < 0 + bias) { //小于1,向0舍入
num = 0;
} else if (exp >= 31 + bias) { //溢出或(int)f == INT_MIN
num = 0x80000000;
} else { //向0舍入
E = exp - bias;
M = frac | 0x800000;
if (E > 23) {
num = M << (E - 23);
} else {
num = M >> (23 - E);
}
}
return sign ? -num : num;
}
#include <stdio.h>
typedef unsigned float_bits;
/*假设i> 0,计算i的位数,例如0x3 => 2、0xFF => 8、0x80 => 8*/
int bits_length(int i) {
if ((i & INT_MIN) != 0) {
return 32;
}
unsigned u = (unsigned)i;
int length = 0;
while (u >= (1<<length)) {
length++;
}
return length;
}
/*计算l的掩码位数,例如3 => 0x00000007、16 => 0x0000FFFF*/
unsigned bits_mask(int l) {
return (unsigned) -1 >> (32-l);
}
/*计算float*/
float_bits float_i2f(int i) {
unsigned sign, exp, frac, rest, exp_sign , round_part;
unsigned bits, fbits;
unsigned bias = 0x7F;
if (i == 0) {
sign = 0;
exp = 0;
frac = 0;
return sign << 31 | exp << 23 | frac;
}
if (i == INT_MIN) {
sign = 1;
exp = bias + 31;
frac = 0;
return sign << 31 | exp << 23 | frac;
}
sign = 0; //确定符号
if (i < 0) {
sign = 1;
i = -i;
}
bits = bits_length(i); //计算i的位数
fbits = bits - 1; //尾数位数
exp = bias + fbits;
rest = i & bits_mask(fbits);
if (fbits <= 23) {
frac = rest << (23 - fbits);
exp_sign = exp << 23 | frac;
} else { //fbits > 23
int offset = fbits - 23;
int round_mid = 1 << (offset - 1); //用于比较,是否舍入位是10
round_part = rest & bits_mask(offset);
frac = rest >> offset;
exp_sign = exp << 23 | frac;
if (round_part < round_mid) { //向偶数舍入,是否舍入位是00
/*无操作*/
} else if (round_part > round_mid) { //是否舍入位是11
exp_sign += 1; //11…->100…
} else { //round_part == round_mid,是否舍入位是10
if ((frac & 0x1) == 1) {
exp_sign += 1; //10…1->10…0
}
}
}
return sign << 31 | exp_sign;
}