Why You Should Never Use == to Compare Floats and Doubles in Java

Picture this: you’ve written a piece of Java code that performs some calculations. The logic seems flawless. You have an if statement that checks if two double or float values are equal. But for some reason, the check keeps failing, even when you’re sure the numbers should be identical. What’s going on? Welcome to one of the most common pitfalls in programming: comparing floating-point numbers.

If you’ve ever written code like if (myDouble == 0.3), you might be in for a surprise. Let’s dive into why this is a bad idea and how to do it correctly.

The Hidden Problem with Floating-Point Numbers

The root of the issue lies in how computers store fractional numbers. Both float and double types in Java use a binary representation format (specifically, the IEEE 754 standard). The problem is that just like the fraction 1/3 cannot be perfectly represented as a finite decimal (it’s 0.33333…), many decimal fractions cannot be perfectly represented in binary.

For example, the number 0.1 in decimal is an infinitely repeating fraction in binary. Because the computer has to truncate this at some point, the value it stores is not exactly 0.1, but a very, very close approximation.

When you perform arithmetic with these approximations, the tiny precision errors can add up, leading to unexpected results.

Continue reading Why You Should Never Use == to Compare Floats and Doubles in Java

Demystifying Thread Safety in Java: A Practical Guide

Imagine you’re collaborating on a Google Doc. You write a sentence, and at the exact same moment, your colleague deletes the paragraph it’s in. The result? Chaos. A corrupted document, lost work, and confusion. This is precisely what can happen inside your Java application when multiple threads—independent paths of execution—try to access and modify the same data simultaneously. Welcome to the world of concurrency and the critical concept of thread safety.

An object or a piece of code is considered “thread-safe” if it continues to function correctly, without causing data corruption or unexpected behavior, even when accessed by multiple threads at the same time. Getting this right is the difference between a robust, predictable application and one that suffers from mysterious, hard-to-reproduce bugs.

The Villain of Our Story: The Race Condition

The most common concurrency problem is the race condition. It occurs when multiple threads “race” to access and change a shared resource, and the final outcome depends on the unpredictable order in which they execute.

Continue reading Demystifying Thread Safety in Java: A Practical Guide

A Practical Guide to TypeScript Logical Operators

In programming, we constantly need to make decisions. Should this code run? Is this user allowed to see that page? To make these decisions, we evaluate conditions, and the fundamental tools for this are logical operators. They are the building blocks of control flow in any language, including TypeScript.

Logical operators work with boolean values (true and false) to produce a single boolean result. Let’s dive into the three core logical operators you’ll use every day: Logical AND (&&), Logical OR (||), and Logical NOT (!).


1. Logical AND (&&)

The Logical AND operator, represented by &&, returns true only if both of its operands are true. If either operand is false, the result will be false.

Think of it like this: “I will go to the park if it is sunny and I have finished my work.” Both conditions must be met.

Truth Table for AND (&&)

Operand AOperand BA && B
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefalse
Continue reading A Practical Guide to TypeScript Logical Operators

8086 Assembly Program to Compute the Greatest Common Divisor (GCD) of Two 16-bit Numbers Using Euclidean Algorithm

In this blog post, we’ll explore an 8086 assembly program that computes the Greatest Common Divisor (GCD) of two numbers using the classic Euclidean Algorithm.

The Euclidean method is an efficient and elegant way to find the largest number that divides both inputs without leaving a remainder.

The principle is simple:
GCD(A, B) = GCD(B, A mod B)

This process repeats until the remainder becomes zero. At that point, the divisor is the GCD.

Let’s dive into the code and understand how it works!


Program Code

data segment
    a dw 0012h          ; First number (18 decimal)
    b dw 000Ah          ; Second number (10 decimal)
    gcd_result dw ?     ; Variable to store the GCD
data ends

code segment
    assume cs:code, ds:data
start:
    mov ax, data
    mov ds, ax           ; Initialize data segment

    mov ax, a            ; Load A into AX
    mov bx, b            ; Load B into BX

    cmp bx, 0000h        ; Check if B is zero
    jz store_result

gcd_loop:
    mov dx, 0000h        ; Clear DX before division
    div bx               ; AX = AX / BX, remainder in DX

    cmp dx, 0000h        ; If remainder = 0, GCD found
    je store_result_bx

    mov ax, bx           ; A = B
    mov bx, dx           ; B = remainder
    jmp gcd_loop         ; Repeat loop

store_result_bx:
    mov ax, bx           ; Move GCD into AX

store_result:
    mov gcd_result, ax   ; Store final result
    int 3                ; Stop execution
code ends
end start

Continue reading 8086 Assembly Program to Compute the Greatest Common Divisor (GCD) of Two 16-bit Numbers Using Euclidean Algorithm

Understanding LinkedHashMap in Java

Let’s dive into a fascinating corner of Java’s Collections Framework: the LinkedHashMap. You might already be familiar with HashMap for its speedy key-value pair storage and LinkedHashSet for maintaining insertion order in a set. Well, LinkedHashMap is the best of both worlds, offering the familiar map interface with the added benefit of predictable iteration order.

Let’s break down what makes LinkedHashMap so special and when you should consider using it.

What is LinkedHashMap?

In simple terms, LinkedHashMap is a hash table and a linked list implementation of the Map interface. It inherits all the goodness from HashMap (fast lookups, insertions, and deletions) but adds an internal doubly-linked list that runs through all of its entries. This linked list defines the iteration order, which can either be:

  1. Insertion Order: The default behavior, where elements are iterated in the order they were first inserted into the map.
  2. Access Order: Elements are iterated in the order they were last accessed (read or written). This is particularly useful for implementing LRU (Least Recently Used) caches.

Like HashMapLinkedHashMap allows one null key and multiple null values.

Interface Hierarchy

LinkedHashMap implements the following interfaces and extends the following class:

  • java.io.Serializable
  • java.util.Map
  • java.lang.Cloneable

And it extends java.util.HashMap.

Continue reading Understanding LinkedHashMap in Java

8086 Assembly Program to Calculate the Factorial of an Integer Using Loops and Registers

In this post, we’ll walk through an 8086 assembly program that calculates the factorial of a given integer. This program highlights the power of the 8086’s loop instruction and the use of general-purpose registers for iterative calculations. We’ll use the AX register as an accumulator for the result and the CX register as a loop counter, which is its special-purpose function. Let’s get to the code!

data segment
    n   dw 5      ; The number to find the factorial of
    fact dw ?     ; To store the 16-bit result
data ends
 
code segment
    assume ds:data, cs:code
start:
    mov ax, data
    mov ds, ax
 
    mov cx, n     ; Load N (5) into the counter register CX
    mov ax, 1     ; Initialize factorial result (AX) to 1
 
fact_loop:
    mul cx        ; Multiply AX by CX. Result in DX:AX
    loop fact_loop ; Decrement CX, jump to fact_loop if CX != 0
 
    mov fact, ax  ; Store the final result from AX into 'fact'
 
    int 3         ; Halt execution (breakpoint for debugging)
code ends
end start
Continue reading 8086 Assembly Program to Calculate the Factorial of an Integer Using Loops and Registers

Custom Validation in Spring Boot: Beyond the Basics!

We’ve all been there – building a Spring Boot application, slapping on a @NotBlank or @Size annotation, and feeling pretty good about our data integrity. But what happens when our validation needs get a little… funkier? What if we need to check if a String contains specific keywords, or ensure two fields have a particular relationship?

That’s where Spring’s custom validation truly shines! While the built-in validators are fantastic for common scenarios, understanding how to roll your own opens up a whole new world of robust data handling. In this post, we’re going to dive into creating custom validators, making our Spring Boot apps even smarter.


Why Custom Validation?

Imagine a scenario where you’re building a user registration form. You might have these requirements:

  • Password Complexity: Must contain at least one uppercase, one lowercase, one digit, and one special character.
  • Username Uniqueness (Client-side): While server-side uniqueness is a given, you might want to prevent common or reserved usernames.
  • Date Range Check: An ‘end date’ must always be after a ‘start date’.

These go beyond what @NotNull or @Min can handle. That’s our cue for custom validation!

Continue reading Custom Validation in Spring Boot: Beyond the Basics!