• mina86.com

  • Categories
  • Code
  • Contact
  • Reading order of The Witcher

    Posted by Michał ‘mina86’ Nazarewicz on 31st of July 2022

    Updated in November 2024 to include Crossroads of Ravens.

    Without beating around the bush, the reading order for the Witcher books is as follows:

    1.The Last WishShort
    stories
    2.Sword of Destiny
    3.Blood of ElvesThe Witcher Saga
    4.Time of Contempt
    5.Baptism of Fire
    6.The Tower of the Swallow
    7.The Lady of the Lake
    8.Season of Storms
    9.Crossroads of Ravens

    Curious case of missing π

    Posted by Michał ‘mina86’ Nazarewicz on 28th of June 2022

    π is one of those constants which pops up when least expected. At the same time it’s sometimes missing when most needed. For example, consider the following application calculating area of a disk (not to be confused with area of a circle which is zero):

    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char **argv) {
    	for (int i = 1; i < argc; ++i) {
    		const double r = atof(argv[i]);
    		printf("%f\n", M_PI * r * r);
    	}
    }

    It uses features introduced in the 1999 edition of the C standard (often referred to as C99) so it might be good to inform the compiler of that fact with a -std=c99 flag. Unfortunately, doing so leads to an error:

    $ gcc -std=c99 -o area area.c
    area.c: In function ‘main’:
    area.c:8:18: error: ‘M_PI’ undeclared (first use in this function)
        8 |   printf("%f\n", M_PI * r * r);
          |                  ^~~~

    What’s going on? Shouldn’t math.h provide the definition of M_PI symbol? It’s what the specification claims after all. ‘glibc is broken’ some may even proclaim. In this article I’ll explain why the compiler conspire with the standard library to behave this way and why it’s the only valid thing it can do.

    Pro tip: You can put URLs in C & C++ code

    Posted by Michał ‘mina86’ Nazarewicz on 1st of April 2022

    Documenting source code is important part of software engineering. Code is read more often than it’s written making it crucial to provide enough context for reader to understand what the implementation is doing. This can come in the form of links to external resources providing description of an algorithm, reference for an API or historic context justifying the code.

    As it turns out, C and C++ languages offer a little-known feature which allows URLs to be included directly in the function source code. For example:

    static float rsqrt(float x) {
    	https://en.wikipedia.org/wiki/Fast_inverse_square_root
    	static_assert(std::numeric_limits<float>::is_iec559);
    	auto i = std::bit_cast<uint32_t>(x) >> 1;
    	auto y = std::bit_cast<float>(UINT32_C(0x5F375A86) - i);
    	y *= 1.5f - x * 0.5F * y * y;
    	return y;
    }

    Primes ≤ 100 in Rust

    Posted by Michał ‘mina86’ Nazarewicz on 20th of June 2021

    In a past life I’ve talked about a challenge to write the shortest program which prints all prime numbers less than a hundred. Back then I’ve discussed a 60-character long solution written in C. Since Rust is the future, inspired by a recent thread on Sieve of Eratosthenes I’ve decided to carry the task for Rust as well.

    To avoid spoiling the solution, I’m padding this article with a bit of unrelated content. To jump straight to the code, skip the next block of paragraphs. Otherwise, here’s a joke for ya:

    How do balanced audio cables work

    Posted by Michał ‘mina86’ Nazarewicz on 13th of June 2021

    Have you ever wondered how balanced audio cables work? For the longest time I have until finally deciding to look into it. Turns out the principle is actually rather straightforward.

    In a normal, unbalanced wire an analogue signal S is sent over a pair of wires: one carries the signal while the other a reference zero. Receiver interprets voltage between the two as the signal. The issue is that over the length of a cable noise is introduced. While transmitter sends S, receiver gets S + e (where e denotes the noise).

    TransmitterReceivernoise
    Illustration of transmission of an analogue signal over a balanced cable. For brevity the diagram missuses symbols from digital signal processing and should not be taken as a technically correct representation.

    A balanced cable addresses this problem by sending the information over three wires: hot (or positive), cold (or negative) and ground. Hot wire carries the signal S as before, cold one carries the inverse of the signal -S and ground is zero as before. Like before, when information travels over the cable, noise is introduced. Crucially, because it’s a single cable, noise on the positive and negative wires are strongly correlated. Receiver therefore gets S + e on hot wire and -S + e on cold wire. All it needs to do is inverse the signal on negative wire and add both signals together. Inversion changes phase of the noises on the cold wire such that it cancels out error remaining on the positive wire: (S + e) + -(-S + e) = S + e + S - e → S.

    Explicit isn’t better than implicit

    Posted by Michał ‘mina86’ Nazarewicz on 6th of June 2021

    Continuing the new tradition of clickbaity titles, let’s talk about explicitness. It’s a subject that comes up when bike-shedding language and API designs. Pointing out that a construct or a function exhibits implicit behaviour is often taunted as an ultimate winning argument against it.

    There are two problems with such line of reasoning. First of all, people claim to care about feature being explicit but came to accept a lot of implicit behaviour without batting an eye. Second of all, no one actually agrees what the terms mean.

    In this article I’ll demonstrate those two issues and show that ‘explicit over implicit’ is the wrong value to uphold. It’s merely a proxy for a much more useful goal interfaces should strive for. By the end I’ll demonstrate what we should look at instead.

    Programmer (vs) Dvorak

    Posted by Michał ‘mina86’ Nazarewicz on 30th of May 2021

    Updated in October 2021 to include direct comparison shift usage between Dvorak and Programmer Dvorak layouts.

    A few years age I’ve made a decision that had the potential to change the course of history. Had I went a different path, the pl(dvp) layout might have never seen the light of day. But did I make a wise choice? Or had I chosen poorly?

    I’m talking of course about the decision to learn Programmer Dvorak rather than a regular Dvorak keyboard layout. The main differences between the two is that in the former digits are entered with Shift key pressed down which allows several punctuation marks often used when programming to be typed without the need to reach for Shift. The hypothesis goes that developers use digits less often thus such design optimises the layout for them.

    To test this I’ve grabbed all my git repositories and constructed a histogram of characters used in text files present there. Since letters are on the same position on both layouts in question, only digits and punctuation characters are compared on the histogram:

    Not number rowUnshifted (number row)Shifted (number row)-".)(,/*=_;0>:<12'#{}438\569$[7]&+!%|@`?~^52%29%19%
    Fig. 1. Histogram of characters used in text files authored by me present in my Git repositories.

    Computer Science vs Reality

    Posted by Michał ‘mina86’ Nazarewicz on 23rd of May 2021

    Robin: ‘Let’s use a linked li—’; Batman: *slaps Robin* ‘Vector is faster’

    Some years ago, during a friendly discussion about C++, a colleague challenged me with a question: what’s the best way to represent a sequence of numbers if delete operation is one that needs to be supported. I argued in favour of a linked list suggesting that with sufficiently large number of elements, it would be much preferred.

    In a twist of fate, I’ve been recently discussing an algorithm which reminded my of that conversation. Except this time I was the one arguing against a node-based data structure. Rather than ending things at a conversation, I’ve decided to benchmark a few solutions to make sure which approach is the best.

    The problem

    The task at hand is simple. Design a data structure which stores a set of words, all of the same length, and offers lookup operation which returns all words matching globs in the form ‘prefix*suffix’. That is, words which start with a given prefix and end with a given suffix. Either part of the pattern may be empty and their concatenation is never longer than length of the words in the collection. Initialisation time and memory footprint are not a concern. Complexity of returning a result can be assumed to be constant.

    In this article I’me going to describe possible solutions — some using a boring vector while others taking advantage of an exciting prefix tree — and benchmark the implementations in an ultimate battle between contiguous-memory-based and a node-based containers.

    Embrace the Bloat

    Posted by Michał ‘mina86’ Nazarewicz on 16th of May 2021

    ‘I’m using slock as my screen locker,’ a wise man once said. He had a beard so surely he was wise.

    ‘Oh?’ his colleague raised a brow intrigued. ‘Did they fix the PAM bug?’ he prodded inquisitively. Nothing but a confused stare came in reply. ‘slock crashes on systems using PAM,’ he offered an explanation and to demonstrate, he approached a nearby machine and pressed the Return key.

    Screens, blanked by a locker a few minutes prior, came back to life, unlocked without the need to enter the password.

    The L*u*v* and LChuv colour spaces

    Posted by Michał ‘mina86’ Nazarewicz on 9th of May 2021

    I’ve written about L*a*b* so it’s only fair that I’ll also describe its twin sister: the L*u*v* colour space (a.k.a. CIELUV). The two share a lot in common. For example, they use the same luminance value, base their chromaticity on opponent process theory and each of them has a corresponding cylindrical LCh coordinate system. Yet, despite those similarities — or perhaps because of them — the CIELUV colour space is often overlooked.

    Panther Chameleon
    Fig. 1. Picture of a chameleon with its decomposition into L*, u* and v* channels. Photo by Dr Pratt Datta.

    Even though L*a*b* is getting all the limelight, L*u*v* model has its advantages. Before we start comparing the two colour spaces, let’s first go through the conversion formulæ.