hello dear hackers hope you are doing great, and correct you have read that title correctly also it’s accepted by developers but how does it actually works ? i will be explaining how does every programming language affect to this Vulnerability and why and gonna see some practical examples also the vulnerability called ( CWE-1077: Floating Point Comparison with Incorrect Operator)
1
2
3
4
5
6
7
| a = 0.1
b = 0.2
sum_result = a + b
target_value = 0.3
print(f"Sum Result: {sum_result}")
print(f"Target Value: {target_value}")
|
and the result is 0.30000000000000004
but should be 0.3
when we do using calculator see figure calculator
below
1
2
| Sum Result: 30000000000000004
Target Value: 0.3
|
now implement this all languages
Python:
1
2
3
4
5
6
7
8
9
10
11
12
| a = 0.1
b = 0.2
sum_result = a + b
target_value = 0.3
print(f"Sum Result: {sum_result}")
print(f"Target Value: {target_value}")
if sum_result == target_value:
print("Equal")
else:
print("Not Equal")
|
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| public class FloatingPointComparison {
public static void main(String[] args) {
double a = 0.1;
double b = 0.2;
double sumResult = a + b;
double targetValue = 0.3;
System.out.println("Sum Result: " + sumResult);
System.out.println("Target Value: " + targetValue);
if (sumResult == targetValue) {
System.out.println("Equal");
} else {
System.out.println("Not Equal");
}
}
}
|
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
| let a = 0.1;
let b = 0.2;
let sumResult = a + b;
let targetValue = 0.3;
console.log(`Sum Result: ${sumResult}`);
console.log(`Target Value: ${targetValue}`);
if (sumResult === targetValue) {
console.log("Equal");
} else {
console.log("Not Equal");
}
|
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| using System;
class Program
{
static void Main()
{
double a = 0.1;
double b = 0.2;
double sumResult = a + b;
double targetValue = 0.3;
Console.WriteLine($"Sum Result: {sumResult}");
Console.WriteLine($"Target Value: {targetValue}");
if (sumResult == targetValue)
{
Console.WriteLine("Equal");
}
else
{
Console.WriteLine("Not Equal");
}
}
}
|
Ruby:
1
2
3
4
5
6
7
8
9
10
11
12
13
| a = 0.1
b = 0.2
sum_result = a + b
target_value = 0.3
puts "Sum Result: #{sum_result}"
puts "Target Value: #{target_value}"
if sum_result == target_value
puts "Equal"
else
puts "Not Equal"
end
|
Swift:
1
2
3
4
5
6
7
8
9
10
11
12
13
| let a = 0.1
let b = 0.2
let sumResult = a + b
let targetValue = 0.3
print("Sum Result: \(sumResult)")
print("Target Value: \(targetValue)")
if sumResult == targetValue {
print("Equal")
} else {
print("Not Equal")
}
|
Certainly, here are the examples in C, C++, Perl, and Bash:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #include <stdio.h>
int main() {
double a = 0.1;
double b = 0.2;
double sum_result = a + b;
double target_value = 0.3;
printf("Sum Result: %lf\n", sum_result);
printf("Target Value: %lf\n", target_value);
if (sum_result == target_value) {
printf("Equal\n");
} else {
printf("Not Equal\n");
}
return 0;
}
|
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #include <iostream>
int main() {
double a = 0.1;
double b = 0.2;
double sum_result = a + b;
double target_value = 0.3;
std::cout << "Sum Result: " << sum_result << std::endl;
std::cout << "Target Value: " << target_value << std::endl;
if (sum_result == target_value) {
std::cout << "Equal" << std::endl;
} else {
std::cout << "Not Equal" << std::endl;
}
return 0;
}
|
Perl:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| use strict;
use warnings;
my $a = 0.1;
my $b = 0.2;
my $sum_result = $a + $b;
my $target_value = 0.3;
print "Sum Result: $sum_result\n";
print "Target Value: $target_value\n";
if ($sum_result == $target_value) {
print "Equal\n";
} else {
print "Not Equal\n";
}
|
Bash:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| #!/bin/bash
a=0.1
b=0.2
sum_result=$(echo "$a + $b" | bc)
target_value=0.3
echo "Sum Result: $sum_result"
echo "Target Value: $target_value"
if [ "$sum_result" = "$target_value" ]; then
echo "Equal"
else
echo "Not Equal"
fi
|
These examples cover C, C++, Perl, and Bash, demonstrating the potential precision issues with floating-point numbers in each language.
These examples showcase the same potential precision issues when directly comparing floating-point numbers for equality. In practice, an epsilon-based approach is recommended for accurate floating-point comparisons.
now how the heck the this hack working and why let’s find out ? but mathemcatically
? yes mathematically
, huhh you look scared mate! but dont worry only the math is gonna help not me, sike!
so let’s dive into the mathematical aspect of floating-point representation and its limitations. We’ll use a simplified example to illustrate the imprecision of representing decimal numbers in binary.
Decimal to Binary Conversion:
- Decimal 0.1 in Binary:
- The decimal fraction 0.1 has a non-terminating binary representation.
- In a typical binary system, it would be represented as 0.00011001100110011… repeating.
- Binary Addition of 0.1 and 0.2:
Let’s add 0.1 and 0.2 in binary:
``` 0.00011001100110011… (0.1 in binary)
0.00110011001100110… (0.2 in binary) ________ 0.01001100110011001… (Sum in binary) ```
Binary to Decimal Conversion:
- Convert Binary Sum to Decimal:
- The binary sum 0.01001100110011001… is converted back to decimal.
1
| 0.01001100110011001... (Sum in binary)
|
The result is a binary fraction with an infinite number of digits.
Rounding Errors:
- Rounding to Finite Precision:
- In computer systems, we cannot store an infinite number of binary digits.
- The result is rounded or truncated to fit within the available bits.
1
| Rounded: 0.01001100110011 (Rounded sum in binary)
|
Implications:
- Imprecision in Arithmetic Operations:
- The rounded sum (binary to decimal) may not exactly match the expected decimal value.
1
2
| Expected Decimal: 0.3
Actual Decimal: 0.299999999999999988897769753748434595763683319091796875
|
i know you aren’t understand the math behind it, but anyway here you can prevent it when coding in these languages here is how we can fix the potential precision issues by using an epsilon-based approach for accurate floating-point comparisons in various programming languages
1. Python:
1
2
3
4
5
6
7
8
9
10
11
| def float_compare(a, b, epsilon=1e-10):
return abs(a - b) < epsilon
# Example usage:
a = 0.1
b = 0.2
epsilon = 1e-10
if float_compare(a + b, 0.3, epsilon):
print("The result is approximately equal to 0.3")
else:
print("The result is not approximately equal to 0.3")
|
2. Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| public class FloatComparison {
public static boolean floatCompare(double a, double b, double epsilon) {
return Math.abs(a - b) < epsilon;
}
public static void main(String[] args) {
double a = 0.1;
double b = 0.2;
double epsilon = 1e-10;
if (floatCompare(a + b, 0.3, epsilon)) {
System.out.println("The result is approximately equal to 0.3");
} else {
System.out.println("The result is not approximately equal to 0.3");
}
}
}
|
3. C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| #include <iostream>
#include <cmath>
bool floatCompare(double a, double b, double epsilon) {
return std::abs(a - b) < epsilon;
}
int main() {
double a = 0.1;
double b = 0.2;
double epsilon = 1e-10;
if (floatCompare(a + b, 0.3, epsilon)) {
std::cout << "The result is approximately equal to 0.3" << std::endl;
} else {
std::cout << "The result is not approximately equal to 0.3" << std::endl;
}
return 0;
}
|
4. JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
| function floatCompare(a, b, epsilon) {
return Math.abs(a - b) < epsilon;
}
let a = 0.1;
let b = 0.2;
let epsilon = 1e-10;
if (floatCompare(a + b, 0.3, epsilon)) {
console.log("The result is approximately equal to 0.3");
} else {
console.log("The result is not approximately equal to 0.3");
}
|
5. Swift:
1
2
3
4
5
6
7
8
9
10
11
12
| func floatCompare(_ a: Double, _ b: Double, _ epsilon: Double) -> Bool {
return abs(a - b) < epsilon
}
let a = 0.1
let b = 0.2
let epsilon = 1e-10
if floatCompare(a + b, 0.3, epsilon) {
print("The result is approximately equal to 0.3")
} else {
print("The result is not approximately equal to 0.3")
}
|
1. Ruby:
1
2
3
4
5
6
7
8
9
10
11
12
13
| def float_compare(a, b, epsilon)
(a - b).abs < epsilon
end
# Example usage:
a = 0.1
b = 0.2
epsilon = 1e-10
if float_compare(a + b, 0.3, epsilon)
puts "The result is approximately equal to 0.3"
else
puts "The result is not approximately equal to 0.3"
end
|
2. Perl:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| sub float_compare {
my ($a, $b, $epsilon) = @_;
return abs($a - $b) < $epsilon;
}
# Example usage:
my $a = 0.1;
my $b = 0.2;
my $epsilon = 1e-10;
if (float_compare($a + $b, 0.3, $epsilon)) {
print "The result is approximately equal to 0.3\n";
} else {
print "The result is not approximately equal to 0.3\n";
}
|
3. Bash:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #!/bin/bash
float_compare() {
local a=$1
local b=$2
local epsilon=$3
local result=$(echo "($a - $b) < $epsilon" | bc)
[ "$result" -eq 1 ]
}
# Example usage:
a=0.1
b=0.2
epsilon=0.000000001
if float_compare "$(echo "$a + $b" | bc)" 0.3 "$epsilon"; then
echo "The result is approximately equal to 0.3"
else
echo "The result is not approximately equal to 0.3"
fi
|
Conclusion:
In mathematical terms, the imprecision arises from the fact that certain decimal fractions cannot be precisely represented in a binary system with a finite number of bits. This leads to rounding errors during arithmetic operations, causing discrepancies between the expected and computed results so Developers must be aware of these limitations when working with floating-point numbers and consider alternative comparison methods, such as epsilon-based comparisons, to handle imprecision appropriately
More Detailed Version with Practical Approach Comming Soon