& U+00026 0010 0110 µ U+000B5 1011 0101 11000010 10110101 ♥ U+02665 0010 0110 0110 0101 11100010 10011001 10100101 Reminder: 7bit 0xxxxxxx 11bit 110xxxxx 10xxxxxx 16bit 1110xxxx 10xxxxxx 10xxxxxx 24bit 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
#include <stdio.h> int main(void) { printf("The unicode code point U+1F600 encodes in UTF-8\n"); printf("as 4 bytes: 0xF0 0x9F 0x98 0x80\n"); printf("We can output the 4 bytes like this: \xF0\x9F\x98\x80\n"); printf("Or like this: "); putchar(0xF0); putchar(0x9F); putchar(0x98); putchar(0x80); putchar('\n'); }
#include <stdio.h> #include <string.h> #include <stdint.h> // UTF-8 encoding of 2665 // 11100010 10011001 10100101 // 11100010 10011001 10100101 // E 2 9 9 A 5 int utf8_num_bytes(uint8_t first_byte); int main(void){ // \u only works for code points with up to 4 hex digits printf("\u2665\n"); printf("\xE2\x99\xA5\n"); char *s = "\u2665 beats"; printf("%s\n",s); printf("♥ beats\n"); //ctrl-shift-u 2665 //string functions DO NOT WORK WITH UNICODE printf("%lu\n",strlen("\u2665")); //3 not 1 printf("%lu\n",strlen(s)); //9 not 7 //using our own function to work out the number //of bytes in unicode character with a given first byte uint8_t first_byte = 0xE2; printf("Expected nbytes for \\x%hhX is %d\n",first_byte, utf8_num_bytes(first_byte)); return 0; } int utf8_num_bytes(uint8_t first_byte){ if ((first_byte & 0x80) == 0) { return 1; } else if ((first_byte & 0xe0) == 0xc0) { return 2; } else if ((first_byte & 0xf0) == 0xe0) { return 3; } else if ((first_byte & 0xf8) == 0xf0) { return 4; } else { fprintf(stderr,"Not a valid first byte\n"); return 0; } }
12.625 12/2 = 6 R0 6/2 = 3 R0 3/2 = 1 R1 1/2 = 0 R1 12: 1100 0.625 * 2 = 1.25 0.25 * 2 = 0.5 0.5 * 2 = 1.0 0.625 = 0.101 12.625: 1100.101 ============= 0.1 * 2 = 0.2 0.2 * 2 = 0.4 0.4 * 2 = 0.8 0.8 * 2 = 1.6 0.6 * 2 = 1.2 0.2 * 2 = 0.4 0.4 * 2 = 0.8 0.8 * 2 = 1.6 0.6 * 2 = 1.2 0.0001100110011001100110011001100110011
``` $ ./floating_types float 4 bytes min=1.17549e-38 max=3.40282e+38 double 8 bytes min=2.22507e-308 max=1.79769e+308 long double 16 bytes min=3.3621e-4932 max=1.18973e+4932 ```
#include <stdio.h> #include <float.h> int main(void) { float f; double d; long double l; printf("float %2lu bytes min=%-12g max=%g\n", sizeof f, FLT_MIN, FLT_MAX); printf("double %2lu bytes min=%-12g max=%g\n", sizeof d, DBL_MIN, DBL_MAX); printf("long double %2lu bytes min=%-12Lg max=%Lg\n", sizeof l, LDBL_MIN, LDBL_MAX); return 0; }
#include <stdio.h> int main(void) { double d = 4/7.0; // prints in decimal with (default) 6 decimal places printf("%lf\n", d); // prints 0.571429 // prints in scientific notation printf("%le\n", d); // prints 5.714286e-01 // picks best of decimal and scientific notation printf("%lg\n", d); // prints 0.571429 // prints in decimal with 9 decimal places printf("%.9lf\n", d); // prints 0.571428571 // prints in decimal with 1 decimal place and field width of 5 printf("%10.1lf\n", d); // prints 0.6 return 0; }
#include <stdio.h> #include <math.h> int main(void) { double x = 1.0/0.0; printf("%lf\n", x); //prints inf printf("%lf\n", -x); //prints -inf printf("%lf\n", x - 1); // prints inf printf("%lf\n", 2 * atan(x)); // prints 3.141593 printf("%d\n", 42 < x); // prints 1 (true) printf("%d\n", x == INFINITY); // prints 1 (true) return 0; }
#include <stdio.h> #include <math.h> int main(void) { double x = 0.0/0.0; printf("%lf\n", x); //prints nan printf("%lf\n", x - 1); // prints nan printf("%d\n", x == x); // prints 0 (false) printf("%d\n", isnan(x)); // prints 1 (true) return 0; }
Convert 1 to floating point representation 1 = 1.0 * 2^0 sign: 0 exp: 0 + 127 = 01111111 frac: 1.0 00111111100000000000000000000000 (1) ======================================== Convert to decimal 0 10000000 11000000000000000000000 sign: +ve exp: 10000000 = 128 - 127 = 1 frac: 1.11 answer = 1.11*2^1 = 11.1 = 3.5 =========================================== Convert to decimal 1 01111110 10000000000000000000000 sign: -ve exp: 01111110 = 126 - 127 = -1 frac: 1.1 answer = -1.1*2^-1 = -0.11 = -0.75 ================================ Extra example: 0 10000000 10000000000000000000000 sign: +ve exp: 10000000 = 128 - 127 = 1 fraction: 1.1 result: 1.1 * 2^1 = 11 = 3
#include <stdio.h> int main(void) { double a, b; a = 0.1; b = 1 - (a + a + a + a + a + a + a + a + a + a); if (b != 0) { // better would be fabs(b) > 0.000001 printf("1 != 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1\n"); } printf("b = %g\n", b); // prints 1.11022e-16 return 0; }
- 9007199254740993 is $2^{53} + 1$ \ it is smallest integer which can not be represented exactly as a double - The closest double to 9007199254740993 is 9007199254740992.0 - aside: 9007199254740993 can not be represented by a int32_t \ it can be represented by int64_t
#include <stdio.h> int main(void) { // loop looks to print 10 numbers but actually never terminates double d = 9007199254740990; while (d < 9007199254741000) { printf("%lf\n", d); // always prints 9007199254740992.000000 // 9007199254740993 can not be represented as a double // closest double is 9007199254740992.0 // so 9007199254740992.0 + 1 = 9007199254740992.0 d = d + 1; } return 0; }
#include <stdio.h> int square(int x){ return x*x; } int absVal(int x){ if( x < 0){ return -x; } return x; } int main(int argc, char * argv[]){ int (*fp)(int); fp = □ int n = (*fp)(9); //9*9 printf("answer is %d\n",n);//81 //& is optional fp = &absVal; //8 8 printf("answer is %d %d\n",(*fp)(-8),fp(-8)); printf("%p %p\n",absVal,&absVal); printf("%p %p\n",square,&square); printf("%p\n",&n); return 0; }
#include <stdio.h> struct a{ double p; //8 double pq; //8 char c; //1 char d; //1 //6 }; // = 24 struct b{ char c; //1 byte char p; //1 byte }; //= 2 bytes struct c{ int x; //4 char c; //1 //3 double f; //8 char s[3];//3 //5 // = 24 bytes }; int main(void){ printf("size of %ld\n",sizeof(struct a)); printf("size of %ld\n",sizeof(struct b)); printf("size of %ld\n",sizeof(struct c)); return 0; }
#include <stdio.h> void printBytes(unsigned char *ptr, int len); int main(void){ int x = 1; // 0x00000001 // LITTLE 01 00 00 00 // BIG 00 00 00 01 unsigned char * ptr; ptr = (unsigned char *) &x; printf("%x %x %x %x\n",*ptr, *(ptr+1),*(ptr+2),*(ptr+3)); return 0; } /** We write it as 0x00000000 00000000 00000000 00000001 But on our machine is it stored like 0x1000 00000000 BIG 0x1001 00000000 0x1002 00000000 0x1003 00000001 OR 0x1000 00000001 LITTLE 0x1001 00000000 0x1002 00000000 0x1003 00000000 */
#include <stdio.h> void printBytes(unsigned char *ptr, int len); int main(void){ int x = 0xF2A913EF; short y = 0x1234; //2 bytes printf("%x %hx\n",x,y); unsigned char * ptr; ptr = (unsigned char *)&x; printf("%x\n",*ptr); printBytes(ptr,4); //print 4 bytes ptr = (unsigned char *)&y; printBytes(ptr,2); return 0; } void printBytes(unsigned char *ptr, int len){ for(int i =0; i < len; i++){ printf("%x ",*ptr); ptr++; } printf("\n"); }
#include <stdio.h> //In hex array would have //61 62 63 64 00 int main(void){ char bytes[] = "abcd"; printf("%x %x %x %x\n",bytes[0],bytes[1], bytes[2],bytes[3]); unsigned int * x = (unsigned int *) bytes; printf("%d %x\n",*x,*x); return 0; } // 61 // 62 // 63 // 64
#include <stdio.h> #include <stdint.h> int main(void) { uint8_t b; uint32_t u; u = 0x03040506; // load first byte of u b = *(uint8_t *)&u; // prints 6 if little-endian // and 3 if big-endian printf("%d\n", b); }
main: li $t0, 0x03040506 la $t1, u sw $t0, 0($t1) # u = 0x03040506; lb $a0, 0($t1) # b = *(uint8_t *)&u; li $v0, 1 # printf("%d", a0); syscall li $a0, '\n' # printf("%c", '\n'); li $v0, 11 syscall li $v0, 0 # return 0 jr $ra .data u: .space 4