Skip to main content

3 posts tagged with "notes"

View All Tags

ยท 2 min read


Building a simple table of reference for the forgetful๐Ÿ˜‚

Based on:

| Hook | Usage |
| useState | const [count, setCount] = useState(0); |
| useEffect | useEffect(() => {<br/> console.log("run when mounted & when state changes")<br/>})<br/><br/>useEffect(() => {<br/> console.log("run once when mounted")<br/>},[])<br/><br/>useEffect(() => {<br/> console.log("run when state changes")<br/>},[state])<br/><br/>useEffect(() => {<br/> console.log("set tear down function");<br/> return () => console.log("run when tear down");<br/>}) |
| useContext | // share data without passing props<br/>// create<br/>const data = {state:'happy'}<br/>const DataContext = createContext(data);<br/><br/>// wrap<br/>const App = () => {<br/> \<DataContext.Provider value={data.state}><br/> \<ChildComponent /><br/> \</DataContext.Provider><br/>}<br/><br/>// use<br/>const ChildComponent = () => {<br/> const data = useContext(DataContext);<br/> return \<p>{state}\</p>;<br/>} |
| useRef | // for mutable state that does not re-render UI<br/>const count = useRef(0);<br/>count.current++; <br/><br/>// for element from the DOM<br/>const myBtn = useRef(null);<br/>const click = () =>;<br/>return (\<button ref={myBtn}>\</button>); |
| useReducer | // dispatch actions to reducer function<br/>const reducer = (state, action) => {<br/> if (action.type === 'increment') { // or switch<br/> return state + 1;}<br/>}<br/><br/>const [state, dispatch] = useReducer(reducer, 0);<br/><br/>return (<br/> \<button onClick={() => dispatch({type: 'increment'})}>+\</button><br/>); |
| useMemo | // for expensive computation to get return values<br/>useMemo(() => {<br/> return count \*\* 2; // expensive<br/>}, [count]) // recompute when count changes |
| useCallback | // for functions<br/>const showCount = useCallback(() => {<br/> console.log(\`change only when \${count} changes\`);<br/>}, [count])<br/><br/>return (<br/> \<div handler = {showCount}>\</div>;<br/>) |

ยท 8 min read

P.S. The following information is based on various resources from the course CS2100 NUS, certain parts are adapted to include my comments and explanations for my better understanding & review. I will try to include source in relevant section as much as possible to honor the authors' work (Mainly Prof Aaron & Prof Colin & TA Alvin).

P.P.S Half way through the course, I decided to change the way I take notes and therefore the information contained here only cover the first few chapters of the module.

  • Read Array
// while-loop
int readArray(int arr[], int limit) {
int index, input;
printf("Enter up to %d integers, terminating with a negative integer.\n", limit);
index = 0; // Must remember to initialize to zero
scanf("%d", &input);
while (input >= 0) {
arr[index] = input;
scanf("%d", &input);
return index; // Which is the actual array size
// for-loop
int readArray2(int arr[], int limit) {
int index, input;
printf("Enter up to %d integers, terminating with a negative integer.\n", limit);
for (index = 0; index < limit; index ++) {
if (arr[index] < 0) {
scanf("%d", &arr[index]);
return index - 1; // Which is the actual array size
  • Reverse Array
// iterative while-loop
void reverseArray(int arr[], int size) {
int left = 0, right = size - 1, temp;
while (left < right) {
temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
// iteractive for-loop
void reverseArray2(int arr[], int size) {
int start, temp, end = size - 1;
for (start = 0; start < size / 2; start++) {
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
// recursive
void reverseArray3(int arr[], int size) {
reverseArrayRec(arr, 0, size - 1);

void reverseArrayRec(int arr[], int left, int right) {
int temp;
if (left < right) {
temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
reverseArrayRec(arr, left + 1, right - 1);
// recursive C-style : from TA Alvin CS2100
void reverseArray4(int arr[], int size) {
if (size <= 1) {
} else {
temp = arr[0];
arr[0] = arr[size - 1];
arr[size - 1] = temp;
// Add 1 to array pointer => shift pointer by 4 bytes
// => move to next item in array, that is the new base
// => treat it as removing the front and back items,
// hence size - 2
reverseArray4(arr + 1, size - 2)

Sign extension

When we want to represent an n-bit signed integer as an m bit signed integer, where m > n. We do this by copying the sign-bit of the n-bit signed m - n times to the left of the n-bit number to create an m-bit number.

To show that sign extension is value-preserving, we can simply check two cases:

  • If the signed bit is 0, adding 0s to the left is similar to adding 0 to the right of a decimal point. It does not change the value.
  • If the signed bit is 1, adding 1s to the left seems to change the value, but not really. This is because the newly added 1s to the right of the newly added signed bit increases the value while the signed bit decreases the value of the number. This effectively cancels out the changes in value. E.g. Focusing on the value that signed bit and the extended signed bit portion, original: 1001 => -2**3 = -8, extended: 111001 => -2**5 + 2**4 + 2**3 = -8

Addition of two 1's complement number with decimal

  • Sign extend or pad zero to the end so that they are of equal length.
  • Invert all the bits for negative number to use addition.
  • If there is a carry out, add 1 to the result.
  • Check for overflow if the result is opposite sign of A and B.

Converting decimal numbers to fixed-point binary

When doing the rounding

  • 0.0000 is rounded to 0.000.
  • 0.0001 is rounded to 0.001.

Represent decimal value in IEEE 754 format

  • When converting the 32 bits to Hexadecimal, make sure that the signed bit is also included.

Bitwise operations

a = 001010
b = 101011
a | b = 101011
a & b = 001010
a ^ b = 100001
~a = 110101
a << 2 = 101000 # equivalent to a *= 4
a >> 2 = 001010 # equivalent to floor(b /= 4)

Special thing about XOR

x ^ x = 0
x ^ 0 = x

a = 00110
a = 00110
a ^ a = 00000

b = 00000
c = 00110
c ^ b = 00110

Swap without temporary variable, with bitwise operator

void swap(int *a, int *b) {
*a = *a ^ *b
*b = *a ^ *b # equivalent to *a ^ *b ^ *b = *a
*a = *a ^ *b # equivalent to *a ^ *b ^ *a = *b

MIPS Masking


  • andi/ori/xori use zero-extension to fill in upper 32 bits. The operation acts on all 32 bits.
andi x, 1 = x
andi x, 0 = 0
ori x, 0 = x
ori x, 1 = 1
nor x, 0 = ~x
xor x, 1 = ~x
xor x, 0 = x

Set bits 2, 8, 16 to 1 in b, a -> $s0, b -> $s1, c -> $s2โ€‹

# 16th bit is outside the range of immediate, which is only 0 - 15th bit
# use intermediate registers for results
lui $t0, 0b1 # this sets the 16th bit
ori $t0, 0b0000000100000100 # this sets 0 - 15th bit
or $s1, $s1, $t0

Copy over bits 1, 3 of b into aโ€‹

lui $t1, 0b1111111111111111
ori $t1, t1, 0b1111111111110101
and $s0, $s0, $t1 # clear the two bits from a
andi $t0, $s1, 0b0000000000001010 # get the two bits from b
or $s0, $s0, $t0 # copy the bits over

Make bits 2, 4 of c inverse of bits 1, 3 of bโ€‹

xori $t0, $s1, 0b0000000000001010 # this invert and copy
andi $t0, $t0, 0b0000000000001010 # clear everything else
sll $t0, $t0, 1 # shift left to 2, 4
lui $t1, $t1, 0b1111111111111111 # clear out 2, 4 of c, 3 steps, lui, ori, and
ori $t1, $t1, 0b1111111111101011
and $s2, $s2, $t1
or $s2, $s2, $t0 # copy over to c

MIPS arithmetic

a -> $s0 b -> $s1 c -> $s2 d -> $s3

d = 6a + 3(b - 2c) d = 6a + 3b - 6c d = 3(2a + b - 2c) d = 3(2(a - c) + b)

sub $t0, $s0, $s2   # a - c
sll $t0, $t0, 1 # 2(a - c)
add $t0, $t0, $s1 # 2(a - c) + b
sll $s3, $t0, 2 # 4(2(a - c) + b)
sub $s3, $s3, $t0 # 3(2(a - c) + b)

MIPS tracing

add $t0, $s0, $ zero    # make a copy
lui $t1, 0x8000 # set t1 to 1 at MSB and 0 else where
lp: beq $t0, $zero, e # if t0 == zero, exit
andi $t2, $t0, 1 # t2 left with LSB
beq $t2, $zero, s # if t2 LSB == 0, s
xor $s0, $s0, $t1 # invert MSB
s: srl $t0, $t0, 1 # discard LSB
j lp # loop back
e: # exit

What happens when integer overflow in C

  • int is 4 bytes (in sunfire), which is 4 x 8 = 32 bits
  • the range is from -2,147,483,648 (-2^31) through +2,147,483,647(2^31 - 1)
  • This range comes from 32 bits 2s complement representation,
  • from 10000000000000000000000000000000 (smallest negative number)
  • to 01111111111111111111111111111111 (largest positive number)
  • when adding 1 to the largest positive number, it becomes the smallest negative number
  • adding another 1 will make it 10000000000000000000000000000001,
  • which is -2147483647, (literally add 1 to the decimal number)

For an n-bit sign-and-magnitude representation, what is the range of values that can be represented?

  • -(2^(n-1) - 1)
  • 2^(n-1) - 1

1s Complement

  • -x = 2^n - 1 - x (in decimal)
  • -x = 2^n - 1 - x + 1 (in decimal)
  • minus 1 because you want the largest possible values in that base

2s Complement

  • -2^(n - 1)
  • 2^(n-1) - 1
  • Adding A + B
  • Ignore the carry out of the MSB
  • Check for overflow. Overflow occurs if the carry in and the carry out of the MSB are different, or if result is opposite sign of A and B

ยท 5 min read

The initial struggle with Vim is very real, speaking from the perspective of a VScode user. However, after using Vim for a few months, I definitely feel much better and more comfortable with Vim.

Especially for shorter Java programs, one will come to appreciate the simplicity and power of Vim in no time. I won't be making Vim my main code editor in the near future, but I definitely do not hate it anymore.

In this article, I hope to note down the absolutely necessary commands needed to use Vim as a programming "IDE". Nothing fancy ๐Ÿ˜‚

P.S There are far comprehensive/detailed tutorials out there, such as vimtutor(if you have Vim installed, simply type vimtutor in the command line, it will bring you through some basic lessons). What I hope to achieve here is to share my most helpful commands. I won't be explaining much for this is more of a reference that sieves out the essential commands than to introduce them formally.

Super Basic Understanding Of Vimโ€‹

When we start with something like vim and open up the standard Vim editing window, we are going to be in the Command mode where the keys we type/press are supposed to be commands that Vim can understand. This is like a control center where we speak jargon that Vim is listening out for.

The other very important mode that we need to know about is the Insert Mode. This is where we type the text that is meant to be in the body of our program. This is the mode that we are in when we open up a typical text editor such as Notepad or Microsoft Word.

When you are done with your changes in insert mode, you have to return to command mode before you can issue a quit command.

I prefer using Ctrl + c to return to command mode from insert mode because the Esc key can be quite far from the normal typing position and Ctrl + c is within reach.

vim filenameCreate/open a file with given filename
iEnter insert mode
Esc /Ctrl + cQuit insert mode and
return to command mode
:wqSave and quit Vim
:q!Discard changes and quit Vim
Code Related
gg=GFix code indentation
ctrl + nAuto word completion
:!javac *.javaCompile code without quitting Vim
hjklthe equivalent arrow keys
ggGo to top of screen
shift + gGo to the bottom of screen
0Go to start of line
$Go to end of line
Ctrl + fPage down
Ctrl + bPage up
rreplace a single character
oadd newline above and enter insert mode
Oadd newline below and enter insert mode
yyCopy line
ddDelete/cut line
dwDelete/cut word
d$Delete/cut from cursor to end of line
xDelete/cut a character

For copying a block of code:

  • press shift + v to start selecting visually by navigating up or down. The block of code will be selected, then press y to copy. Afterward, simply press p to paste.
Common Tasks
Ctrl + rRedo
:s/foo/bar/gFind and replace
"foo" with "bar"
for all "foo"

Multiple tabs
To open a new file in another tab:

  • use :tabe filename
  • e.g. :tabe

To navigate between tabs:

  • use gt to go to next tab
  • use 1gt, 2gt, 3gt to go to different tab by number
  • e.g. 1gt goes to the first tab from the left

To get out of Vim for a while:

  • use ctrl + z to suspend activity
  • use fg (foreground) to come back to Vim
Common UNIX commands
lslist files in current folder
cd <directory>enter this folder
cd ..go out of current folder
rm <file>delete this file
mkdir <directory>make new folder
mv <file1> <file2>Rename file1 as file2
cp <file1> <file2>copy file1 to file2
tabfor auto completion of possible commands

The Endโ€‹

I will be updating this article to add/reflect my latest list of frequently used commands. Bye now!

gif bye

*5/12/2020 P.S. I have updated pretty much whatever I found useful, will continue to update this list in the future as this list also serves as my own notes.