Lowering the Level of Conversation @KevlinHenney

https://twitter.com/KevlinHenney/status/761081424493449217

A completely invalidates the high-level structure of the code.

Taligent's Guide to Designing Programs

/ WordFriday , noun ▪ clichéd wording used as a template, typically originating in a single quote ▪ e.g., "X considered harmful", "These aren't the Xs you're looking for", "X is the new Y", "It's X, but not as we know it", "No X left behind", "It's Xs all the way down", "All your X are belong to us" send(to, from, count) register short *to, *from; register count; { register n=(count+7)/8; switch(count%8){ case 0: do{ *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; }while(--n>0); } } send(to, from, count) register short *to, *from; register count; I feel {a combination of register n=(count+7)/8; switch(count%8){ case 0: do{ *to = *from++; pride andcase 7: revulsion *to = *from++; at case 6: *to = *from++; case 5: *to = *from++; this discovery.case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; }while(--n>0); } Tom Duff } send(to, from, count) register short *to, *from; Many peopleregister have count; said that the worst { feature of Cregister is that n=(count+7)/8; switches don't break switch(count%8){ automaticallycase before 0: do{ *to each = *from++; case label. case 7: *to = *from++; This code formscase 6: some *to sort = *from++; of argument case 5: *to = *from++; in that debate,case but4: I'm *to not = *from++; sure whether it's for or against.case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; }while(--n>0); } Tom Duff }

Earliest informal standard set by 1st edition of The

First de jure standard, included properly typed function declarations (function prototypes), const, better i18n support

First international standard — basically C89 rebadged

Significant update with new language and library features, including better IEEE 754 support, compound literals and portable data types

Support for threading, type-generic expressions and safer bounds-checking library functions

16-bit void * short int long 32-bit void * short int long 32-bit void * short int long long long 64-bit void * short int long long long LP64 void * short int long long long Java & C# short int long LLP64 void * short int long long long int8_t int_least8_t int_fast8_t uint8_t uint_least8_t uint_fast8_t int16_t int_least16_t int_fast16_t uint16_t uint_least16_t uint_fast16_t int32_t int_least32_t int_fast32_t uint32_t uint_least32_t uint_fast32_t int64_t int_least64_t int_fast64_t uint64_t uint_least64_t uint_fast64_t intptr_t uintptr_t Signed magnitude

A sign bit, 0 for + and 1 for –, is followed by the bits representing the integer's magnitude

640210 00011001000000102 -640210 10011001000000102 0 00000000000000002 -0 10000000000000002 One's complement

Negative integers are represented as the bitwise complement of the corresponding positive integer, i.e., –i is equivalent to ~i

640210 00011001000000102 -640210 11100110111111012 0 00000000000000002 -0 11111111111111112 Two's complement

Negative integers are represented 1 plus as the bitwise complement of the corresponding positive integer, i.e., –i is equivalent to ~i + 1, which is the same as saying that it is the complement with respect to 2N

640210 00011001000000102 -640210 11100110111111102 0 00000000000000002 28 256 27-1 127 -27 -128 216 65536 215-1 32767 -215 -32768 232 4294967296 231-1 2147483647 -231 -2147483648 264 18446744073709551616 263-1 9223372036854775807 -263 -9223372036854775808 32767 ______+ 1 ______32768 32767 ______+ 1 undefined______32767 ______+ 1 ______-32768 INT_MIN ______- INT_MIN ______0 INT_MIN ______+ INT_MIN ______0 Extra, Extra - Read All About It: Nearly All Binary Searches and Mergesorts are Broken Joshua Bloch

https://ai.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html I was shocked to learn that the binary search program that Bentley proved correct and subsequently tested in Chapter 5 of Programming Pearls contains a bug.

https://ai.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html Lest you think I'm picking on Bentley, let me tell you how I discovered the bug: The version of binary search that I wrote for the JDK contained the same bug.

https://ai.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html https://ai.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html (low + high) / 2 low / 2 + high / 2 low + (high – low) / 2 time_t int main(void) { const time_t end_of_time = INT_MAX; puts(asctime(gmtime(&end_of_time))); return 0; } Tue Jan 19 03:14:07 2038 int main(void) { const time_t end_of_time = INT_MAX + 1; puts(asctime(gmtime(&end_of_time))); return 0; } Fri Dec 13 20:45:52 1901 printf("%f", 0.1 + 0.2); 0.300000 assert(0.1 + 0.2 == 0.3); assert(0.1 + 0.2 == 0.3); printf("%.17f", 0.1 + 0.2); 0.30000000000000004

Floating-Point Numbers Aren't Real

Chuck Allison Real numbers have infinite precision and are therefore continuous and nonlossy; floating-point numbers have limited precision, so they are finite, and they resemble "badly behaved" integers, because they’re not evenly spaced throughout their range.

Chuck Allison It should go without saying that you shouldn't use floating-point numbers for financial applications — that's what decimal classes in languages like Python and C# are for.

Chuck Allison significand bias exponent single precision 32-bit

double precision 64-bit

extended precision 64-,80- or 128-bit single precision 32-bit IEEE 754

sign biased exponent significand

double same_birthday(int people); // Return the probability that at least 2 people out of a sample // of size 'people' share the same birthday, assuming a uniform // distribution of birthdays and ignoring leap days.

int main(void) { int people = 0; while (same_birthday(people) < 0.5) ++people; printf("%i", people); return 0; } double same_birthday(int people) { double probability = 0; for (int i = 1; i < people; ++i) probability += (1 – probability) * i / 365.0; return probability; } int main(void) { int people = 0; while (same_birthday(people) < 0.5) ++people; printf("%i", people); return 0; }

http://xkcd.com/552/

Correlation doesn't imply causation, but it does waggle its eyebrows suggestively and gesture furtively while mouthing 'look over there'. double same_birthday(int people) { double probability = 0; for (int i = 1; i < people; ++i) probability += (1 - probability) * i / 365.0; return probability; } double same_birthday(int people) { if (people < 0) { errno = EDOM; return NAN; } else { double probability = 0; for (int i = 1; i < people; ++i) probability += (1 - probability) * i / 365.0; return probability; } } double same_birthday(int people) { if (people < 0) { errno = EDOM; return NAN; } else if (people > 365) { return 1; } else { double probability = 0; for (int i = 1; i < people; ++i) probability += (1 - probability) * i / 365.0; return probability; } } assert(same_birthday(0) == 0); assert(same_birthday(1) == 0); assert(same_birthday(2) > 0); ... assert(same_birthday(365) < 1); assert(same_birthday(366) == 1); assert(same_birthday(367) == 1); ... assert(same_birthday(INT_MAX) == 1); assert(same_birthday(0) == 0); assert(same_birthday(1) == 0); assert(same_birthday(2) > 0); ... assert(same_birthday(365) < 1); assert(same_birthday(366) == 1); assert(same_birthday(367) == 1); ... assert(same_birthday(INT_MAX) == 1); assert(same_birthday(0) == 0); assert(same_birthday(1) == 0); assert(same_birthday(2) > 0); ... assert(same_birthday(183) < 1); assert(same_birthday(184) < 1); ... assert(same_birthday(365) < 1); assert(same_birthday(366) == 1); assert(same_birthday(367) == 1); ... assert(same_birthday(INT_MAX) == 1); The real value of tests is not that they detect bugs in the code but that they detect inadequacies in the methods, concentration, and skills of those who design and produce the code.

C A R Hoare double unique_birthday(int people) { if (people < 0) { errno = EDOM; return NAN; } else if (people > 365) { return 0; } else { double probability = 1; const int nonpeople = 366 – people; for (int i = 364; i >= nonpeople; --i) probability *= i / 365.0; return probability; } }

double same_birthday(int people) { if (people < 0) { errno = EDOM; return NAN; } else if (people > 365) { return 1; } else { double probability = 0; for (int i = 1; i < people; ++i) probability += (1 - probability) * i / 365.0; if (probability == 1) --*(uint64_t *) &probability; return probability; } } assert(same_birthday(0) == 0); assert(same_birthday(1) == 0); assert(same_birthday(2) > 0); ... assert(same_birthday(183) < 1); assert(same_birthday(184) < 1); ... assert(same_birthday(365) < 1); assert(same_birthday(366) == 1); assert(same_birthday(367) == 1); ... assert(same_birthday(INT_MAX) == 1); printf("%.15f", same_birthday(365)); 1.000000000000000 printf("%.16f", same_birthday(365)); 0.9999999999999999 double same_birthday(int people) { if (people < 0) { errno = EDOM; return NAN; } else if (people > 365) { return 1; } else { double probability = 0; for (int i = 1; i < people; ++i) probability += (1 - probability) * i / 365.0; if (probability == 1) --*(uint64_t *) &probability; return probability; } } double same_birthday(int people) { if (people < 0) { errno = EDOM; return NAN; } else if (people > 365) { return 1; } else { double probability = 0; for (int i = 1; i < people; ++i) probability += (1 - probability) * i / 365.0; if (probability == 1) --*(uint64_t *) &probability; return probability; } } double same_birthday(int people) { if (people < 0) { errno = EDOM; return NAN; } else if (people > 365) { return 1; } else { double probability = 0; for (int i = 1; i < people; ++i) probability += (1 - probability) * i / 365.0; if (probability == 1) probability = nexttoward(1, 0); return probability; } } double same_birthday(int people) { if (people < 0) { errno = EDOM; return NAN; } else if (people > 365) { return 1; } else { double probability = 0; for (int i = 1; i < people; ++i) probability += (1 - probability) * i / 365.0; return probability < 1 ? probability : nexttoward(1, 0); } }

If a plot works out exactly as you first planned, you're not working loosely enough to give room to your imagination and instincts.

The failure resulted in a loss of more than US$370 million.

http://en.wikipedia.org/wiki/Cluster_(spacecraft)

Simple Testing Can Prevent Most Critical Failures An Analysis of Production Failures in Distributed Data-Intensive Systems

https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf A majority of the production failures (77%) can be reproduced by a unit test.

https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf network code() { switch (line) { case THING1: doit1(); break; case THING2: if (x == STUFF) { do_first_stuff(); if (y == OTHER_STUFF) break; do_later_stuff(); } /* coder meant to break to here... */ initialize_modes_pointer(); break; default: processing(); } /* ...but actually broke to here! */ use_modes_pointer(); /* leaving the modes_pointer uninitialized */ } Peter van der Linden Expert C Programming if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail;

Mike Bland "Goto Fail, Heartbleed, and Unit Testing Culture" https://martinfowler.com/articles/testing-culture.html Goto Fail, Heartbleed, and Unit Testing Culture

Mike Bland https://martinfowler.com/articles/testing-culture.html These bugs are as instructive as they were devastating: They were rooted in the same programmer optimism, overconfidence, and haste that strike projects of all sizes and domains.

Mike Bland https://martinfowler.com/articles/testing-culture.html These bugs arouse my passion because I've seen and lived the benefits of unit testing, and this strongly-imprinted experience compels me to reflect on how unit testing approaches could prevent defects as high- impact and high-profile as these SSL bugs.

Mike Bland https://martinfowler.com/articles/testing-culture.html

Test-Driven Development is not a testing technique, although you do write a lot of valuable automated tests. It is a way to solve programming problems. It helps software developers make good design decisions. Tests provide a clear warning when the solution takes a wrong path or breaks some forgotten constraint. Tests capture the production code’s desired behavior. TDD is fun! It’s like a game where you navigate a maze of technical decisions that lead to highly robust software while avoiding the quagmire of long debug sessions. With each test there is a renewed sense of accomplishment and clear progress toward the goal. Automated tests record assumptions, capture decisions, and free the mind to focus on the next challenge. TDD is fun!

The fastest I/O is no I/O.

Nils-Peter Nelson Command-line tools can be 235x faster than your Hadoop cluster

Adam Drake http://aadrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html c 299792458

http://ithare.com/infographics-operation-costs-in-cpu-clock-cycles/ Low-level programming is good for the programmer's soul.

John Carmack