diff --git a/include/scratchcpp/value.h b/include/scratchcpp/value.h
index c50b8de4..86925a6a 100644
--- a/include/scratchcpp/value.h
+++ b/include/scratchcpp/value.h
@@ -443,18 +443,20 @@ class LIBSCRATCHCPP_EXPORT Value : public ValueVariant
                         }
                 }
             } else {
-                if (v1.isNumber() || v2.isNumber())
+                if (v1.isString() || v2.isString())
+                    return stringsEqual(v1.toUtf16(), v2.toUtf16());
+                else if (v1.isNumber() || v2.isNumber())
                     return v1.toDouble() == v2.toDouble();
                 else if (v1.isBool() || v2.isBool())
                     return ((v1.m_type != Type::NaN && v2.m_type != Type::NaN) && (v1.toBool() == v2.toBool()));
-                else if (v1.isString() || v2.isString())
-                    return stringsEqual(v1.toUtf16(), v2.toUtf16());
                 else
                     return false;
             }
             return false;
         }
 
+        friend bool operator!=(const Value &v1, const Value &v2) { return !(v1 == v2); }
+
         friend bool operator>(const Value &v1, const Value &v2)
         {
             if ((static_cast<int>(v1.m_type) < 0) || (static_cast<int>(v2.m_type) < 0)) {
@@ -660,6 +662,14 @@ class LIBSCRATCHCPP_EXPORT Value : public ValueVariant
                 return 0;
             }
 
+            static const std::string digits = "0123456789+-";
+
+            for (char c : s) {
+                if (digits.find(c) == std::string::npos) {
+                    return 0;
+                }
+            }
+
             try {
                 if (ok)
                     *ok = true;
diff --git a/test/load_project/load_project_test.cpp b/test/load_project/load_project_test.cpp
index 4585ec29..c417fa67 100644
--- a/test/load_project/load_project_test.cpp
+++ b/test/load_project/load_project_test.cpp
@@ -191,7 +191,7 @@ TEST(LoadProjectTest, LoadTestProject)
         ASSERT_EQ(prototype->argumentIds().size(), 2);
         ASSERT_EQ(prototype->argumentNames(), std::vector<std::string>({ "num or text", "bool" }));
         ASSERT_EQ(prototype->argumentTypes(), std::vector<BlockPrototype::ArgType>({ BlockPrototype::ArgType::StringNum, BlockPrototype::ArgType::Bool }));
-        ASSERT_EQ(prototype->argumentDefaults(), std::vector<Value>({ 0, false }));
+        ASSERT_EQ(prototype->argumentDefaults(), std::vector<Value>({ "", false }));
         ASSERT_EQ(prototype->procCode(), "custom block %s %b");
         ASSERT_INPUT(blockPrototype, prototype->argumentIds()[0]);
         auto argBlock = GET_INPUT(blockPrototype, prototype->argumentIds()[0])->valueBlock();
diff --git a/test/scratch_classes/value_test.cpp b/test/scratch_classes/value_test.cpp
index 2a5d14c3..234f092b 100644
--- a/test/scratch_classes/value_test.cpp
+++ b/test/scratch_classes/value_test.cpp
@@ -123,6 +123,30 @@ TEST(ValueTest, StdStringConstructor)
         ASSERT_TRUE(v.isString());
     }
 
+    {
+        Value v(std::string("532"));
+        ASSERT_EQ(v.toString(), "532");
+        ASSERT_EQ(v.type(), Value::Type::Number);
+        ASSERT_FALSE(v.isInfinity());
+        ASSERT_FALSE(v.isNegativeInfinity());
+        ASSERT_FALSE(v.isNaN());
+        ASSERT_TRUE(v.isNumber());
+        ASSERT_FALSE(v.isBool());
+        ASSERT_FALSE(v.isString());
+    }
+
+    {
+        Value v(std::string("1 2 3"));
+        ASSERT_EQ(v.toString(), "1 2 3");
+        ASSERT_EQ(v.type(), Value::Type::String);
+        ASSERT_FALSE(v.isInfinity());
+        ASSERT_FALSE(v.isNegativeInfinity());
+        ASSERT_FALSE(v.isNaN());
+        ASSERT_FALSE(v.isNumber());
+        ASSERT_FALSE(v.isBool());
+        ASSERT_TRUE(v.isString());
+    }
+
     {
         Value v(std::string("Infinity"));
         ASSERT_EQ(v.toString(), "Infinity");
@@ -1443,3 +1467,371 @@ TEST(ValueTest, ModOperator)
     v = -150;
     ASSERT_EQ(v % "-Infinity", -150);
 }
+
+TEST(ValueTest, EqualityOperators)
+{
+    {
+        Value v1 = 10;
+        Value v2 = 10;
+        Value v3 = 8;
+
+        ASSERT_TRUE(v1 == v2);
+        ASSERT_FALSE(v1 != v2);
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v2 == v3);
+        ASSERT_TRUE(v2 != v3);
+    }
+
+    {
+        Value v1 = -4.25;
+        Value v2 = -4.25;
+        Value v3 = 5.312;
+
+        ASSERT_TRUE(v1 == v2);
+        ASSERT_FALSE(v1 != v2);
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v2 == v3);
+        ASSERT_TRUE(v2 != v3);
+    }
+
+    {
+        Value v1 = true;
+        Value v2 = true;
+        Value v3 = false;
+
+        ASSERT_TRUE(v1 == v2);
+        ASSERT_FALSE(v1 != v2);
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v2 == v3);
+        ASSERT_TRUE(v2 != v3);
+    }
+
+    {
+        Value v1 = "abC def";
+        Value v2 = "abC def";
+        Value v3 = "abc dEf";
+        Value v4 = "hello world";
+
+        ASSERT_TRUE(v1 == v2);
+        ASSERT_FALSE(v1 != v2);
+
+        ASSERT_TRUE(v1 == v3);
+        ASSERT_FALSE(v1 != v3);
+
+        ASSERT_TRUE(v2 == v3);
+        ASSERT_FALSE(v2 != v3);
+
+        ASSERT_FALSE(v1 == v4);
+        ASSERT_TRUE(v1 != v4);
+
+        ASSERT_FALSE(v2 == v4);
+        ASSERT_TRUE(v2 != v4);
+
+        ASSERT_FALSE(v3 == v4);
+        ASSERT_TRUE(v3 != v4);
+    }
+
+    {
+        Value v1(Value::SpecialValue::Infinity);
+        Value v2(Value::SpecialValue::Infinity);
+        Value v3(Value::SpecialValue::NegativeInfinity);
+        Value v4(Value::SpecialValue::NegativeInfinity);
+        Value v5(Value::SpecialValue::NaN);
+        Value v6(Value::SpecialValue::NaN);
+
+        ASSERT_TRUE(v1 == v2);
+        ASSERT_FALSE(v1 != v2);
+
+        ASSERT_TRUE(v3 == v4);
+        ASSERT_FALSE(v3 != v4);
+
+        // TODO: Enable this after #196 is fixed
+        /*ASSERT_TRUE(v5 == v6);
+        ASSERT_FALSE(v5 != v6);*/
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v1 == v5);
+        ASSERT_TRUE(v1 != v5);
+
+        ASSERT_FALSE(v3 == v5);
+        ASSERT_TRUE(v3 != v5);
+    }
+
+    {
+        Value v1 = 5.00;
+        Value v2 = 5;
+        Value v3 = 6;
+
+        ASSERT_TRUE(v1 == v2);
+        ASSERT_FALSE(v1 != v2);
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v2 == v3);
+        ASSERT_TRUE(v2 != v3);
+    }
+
+    {
+        Value v1 = 1;
+        Value v2 = true;
+        Value v3 = false;
+
+        ASSERT_TRUE(v1 == v2);
+        ASSERT_FALSE(v1 != v2);
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v2 == v3);
+        ASSERT_TRUE(v2 != v3);
+    }
+
+    {
+        Value v1 = 5.25;
+        Value v2 = "5.25";
+        Value v3 = "5.26";
+
+        ASSERT_TRUE(v1 == v2);
+        ASSERT_FALSE(v1 != v2);
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v2 == v3);
+        ASSERT_TRUE(v2 != v3);
+    }
+
+    {
+        Value v1 = 0;
+        Value v2 = "0";
+        Value v3 = "1";
+        Value v4 = "test";
+
+        ASSERT_TRUE(v1 == v2);
+        ASSERT_FALSE(v1 != v2);
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v1 == v4);
+        ASSERT_TRUE(v1 != v4);
+    }
+
+    {
+        Value v1 = 1;
+        Value v2 = true;
+        Value v3 = false;
+
+        ASSERT_TRUE(v1 == v2);
+        ASSERT_FALSE(v1 != v2);
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v2 == v3);
+        ASSERT_TRUE(v2 != v3);
+    }
+
+    {
+        Value v1 = 5;
+        Value v2 = 0;
+        Value v3(Value::SpecialValue::Infinity);
+        Value v4(Value::SpecialValue::NegativeInfinity);
+        Value v5(Value::SpecialValue::NaN);
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v1 == v4);
+        ASSERT_TRUE(v1 != v4);
+
+        ASSERT_FALSE(v1 == v5);
+        ASSERT_TRUE(v1 != v5);
+
+        // TODO: Enable this after #198 is fixed
+        /*ASSERT_FALSE(v2 == v5);
+        ASSERT_TRUE(v2 != v5);*/
+    }
+
+    {
+        Value v1 = true;
+        Value v2 = false;
+        Value v3 = "true";
+        Value v4 = "false";
+        Value v5 = "TRUE";
+        Value v6 = "FALSE";
+
+        ASSERT_TRUE(v1 == v3);
+        ASSERT_FALSE(v1 != v3);
+
+        ASSERT_TRUE(v2 == v4);
+        ASSERT_FALSE(v2 != v4);
+
+        ASSERT_FALSE(v1 == v2);
+        ASSERT_TRUE(v1 != v2);
+
+        ASSERT_FALSE(v2 == v3);
+        ASSERT_TRUE(v2 != v3);
+
+        ASSERT_TRUE(v1 == v5);
+        ASSERT_FALSE(v1 != v5);
+
+        ASSERT_TRUE(v2 == v6);
+        ASSERT_FALSE(v2 != v6);
+    }
+
+    {
+        Value v1 = true;
+        Value v2 = false;
+        Value v3(Value::SpecialValue::Infinity);
+        Value v4(Value::SpecialValue::NegativeInfinity);
+        Value v5(Value::SpecialValue::NaN);
+
+        ASSERT_FALSE(v1 == v3);
+        ASSERT_TRUE(v1 != v3);
+
+        ASSERT_FALSE(v1 == v4);
+        ASSERT_TRUE(v1 != v4);
+
+        ASSERT_FALSE(v1 == v5);
+        ASSERT_TRUE(v1 != v5);
+
+        ASSERT_FALSE(v2 == v5);
+        ASSERT_TRUE(v2 != v5);
+    }
+
+    {
+        Value v1 = "Infinity";
+        Value v2 = "infinity";
+        Value v3 = "-Infinity";
+        Value v4 = "-infinity";
+        Value v5 = "NaN";
+        Value v6 = "nan";
+        Value v7(Value::SpecialValue::Infinity);
+        Value v8(Value::SpecialValue::NegativeInfinity);
+        Value v9(Value::SpecialValue::NaN);
+
+        // Infinity
+        ASSERT_TRUE(v1 == v7);
+        ASSERT_FALSE(v1 != v7);
+
+        ASSERT_FALSE(v1 == v8);
+        ASSERT_TRUE(v1 != v8);
+
+        ASSERT_FALSE(v1 == v9);
+        ASSERT_TRUE(v1 != v9);
+
+        // infinity
+        ASSERT_TRUE(v2 == v7);
+        ASSERT_FALSE(v2 != v7);
+
+        ASSERT_FALSE(v2 == v8);
+        ASSERT_TRUE(v2 != v8);
+
+        ASSERT_FALSE(v2 == v9);
+        ASSERT_TRUE(v2 != v9);
+
+        // -Infinity
+        ASSERT_FALSE(v3 == v7);
+        ASSERT_TRUE(v3 != v7);
+
+        ASSERT_TRUE(v3 == v8);
+        ASSERT_FALSE(v3 != v8);
+
+        ASSERT_FALSE(v3 == v9);
+        ASSERT_TRUE(v3 != v9);
+
+        // -infinity
+        ASSERT_FALSE(v4 == v7);
+        ASSERT_TRUE(v4 != v7);
+
+        ASSERT_TRUE(v4 == v8);
+        ASSERT_FALSE(v4 != v8);
+
+        ASSERT_FALSE(v4 == v9);
+        ASSERT_TRUE(v4 != v9);
+
+        // NaN
+        ASSERT_FALSE(v5 == v7);
+        ASSERT_TRUE(v5 != v7);
+
+        ASSERT_FALSE(v5 == v8);
+        ASSERT_TRUE(v5 != v8);
+
+        // TODO: Enable this after #197 is fixed
+        /*ASSERT_TRUE(v5 == v9);
+        ASSERT_FALSE(v5 != v9);*/
+
+        // nan
+        ASSERT_FALSE(v6 == v7);
+        ASSERT_TRUE(v6 != v7);
+
+        ASSERT_FALSE(v6 == v8);
+        ASSERT_TRUE(v6 != v8);
+
+        ASSERT_TRUE(v6 == v9);
+        ASSERT_FALSE(v6 != v9);
+    }
+
+    {
+        Value v1 = "abc";
+        Value v2 = " ";
+        Value v3 = "";
+        Value v4 = "0";
+        Value v5(Value::SpecialValue::Infinity);
+        Value v6(Value::SpecialValue::NegativeInfinity);
+        Value v7(Value::SpecialValue::NaN);
+
+        // Infinity
+        ASSERT_FALSE(v1 == v5);
+        ASSERT_TRUE(v1 != v5);
+
+        ASSERT_FALSE(v2 == v5);
+        ASSERT_TRUE(v2 != v5);
+
+        ASSERT_FALSE(v3 == v5);
+        ASSERT_TRUE(v3 != v5);
+
+        ASSERT_FALSE(v4 == v5);
+        ASSERT_TRUE(v4 != v5);
+
+        // -Infinity
+        ASSERT_FALSE(v1 == v6);
+        ASSERT_TRUE(v1 != v6);
+
+        ASSERT_FALSE(v2 == v6);
+        ASSERT_TRUE(v2 != v6);
+
+        ASSERT_FALSE(v3 == v6);
+        ASSERT_TRUE(v3 != v6);
+
+        ASSERT_FALSE(v4 == v6);
+        ASSERT_TRUE(v4 != v6);
+
+        // NaN
+        ASSERT_FALSE(v1 == v7);
+        ASSERT_TRUE(v1 != v7);
+
+        ASSERT_FALSE(v2 == v7);
+        ASSERT_TRUE(v2 != v7);
+
+        ASSERT_FALSE(v3 == v7);
+        ASSERT_TRUE(v3 != v7);
+
+        // TODO: Enable this after #198 is fixed
+        /*ASSERT_FALSE(v4 == v7);
+        ASSERT_TRUE(v4 != v7);*/
+    }
+}
diff --git a/test/virtual_machine/virtual_machine_test.cpp b/test/virtual_machine/virtual_machine_test.cpp
index aa34ec1a..8edc8771 100644
--- a/test/virtual_machine/virtual_machine_test.cpp
+++ b/test/virtual_machine/virtual_machine_test.cpp
@@ -830,7 +830,7 @@ TEST(VirtualMachineTest, OP_LIST_APPEND)
     ASSERT_EQ(list1[0], 3.52);
 
     ASSERT_EQ(list2.size(), 1);
-    ASSERT_EQ(list2[1], "test");
+    ASSERT_EQ(list2[0], "test");
 
     ASSERT_EQ(vm.registerCount(), 0);
 }
