diff --git a/src/main/resources/dictionaries/ideavim.dic b/src/main/resources/dictionaries/ideavim.dic
index 35af1df6f..a6ec1f5e8 100644
--- a/src/main/resources/dictionaries/ideavim.dic
+++ b/src/main/resources/dictionaries/ideavim.dic
@@ -170,6 +170,7 @@ funcref
 getcmdtype
 getreg
 getregtype
+isinf
 tolower
 toupper
 
diff --git a/src/main/resources/messages/IdeaVimBundle.properties b/src/main/resources/messages/IdeaVimBundle.properties
index ebe7fb462..92ca2490b 100644
--- a/src/main/resources/messages/IdeaVimBundle.properties
+++ b/src/main/resources/messages/IdeaVimBundle.properties
@@ -88,6 +88,7 @@ E730=E730: Using a List as a String
 E731=E731: Using a Dictionary as a String
 E774=E774: 'operatorfunc' is empty
 E805=E805: Using a Float as a Number
+E808=E808: Number or Float required
 e841.reserved.name.cannot.be.used.for.user.defined.command=E841: Reserved name, cannot be used for user defined command
 E939=E939: Positive count required
 E1211=E1211: List required for argument {0}
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AbsFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AbsFunctionTest.kt
index 469666394..0a1baf108 100644
--- a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AbsFunctionTest.kt
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AbsFunctionTest.kt
@@ -21,7 +21,37 @@ class AbsFunctionTest : VimTestCase() {
   }
 
   @Test
-  fun `test abs`() {
-    assertCommandOutput("echo abs(-123) abs(2)", "123 2")
+  fun `test abs with float value`() {
+    assertCommandOutput("echo abs(1.456)", "1.456")
+    assertCommandOutput("echo abs(-5.456)", "5.456")
+  }
+
+  @Test
+  fun `test abs with integer value`() {
+    assertCommandOutput("echo abs(-4)", "4")
+  }
+
+  @Test
+  fun `test abs with coerced float value`() {
+    assertCommandOutput("""echo abs("-5.456")""", "5")
+  }
+
+  @Test
+  fun `test abs with coerced integer value`() {
+    assertCommandOutput("""echo abs("-4")""", "4")
+  }
+
+  @Test
+  fun `test abs with list causes error`() {
+    enterCommand("""echo abs([-5.456])""")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E745: Using a List as a Number")
+  }
+
+  @Test
+  fun `test abs with dictionary causes error`() {
+    enterCommand("""echo abs({1: -5.456})""")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E728: Using a Dictionary as a Number")
   }
 }
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AcosFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AcosFunctionTest.kt
new file mode 100644
index 000000000..5e60bcc81
--- /dev/null
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AcosFunctionTest.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package org.jetbrains.plugins.ideavim.ex.implementation.functions.floatFunctions
+
+import org.jetbrains.plugins.ideavim.VimTestCase
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInfo
+
+class AcosFunctionTest : VimTestCase() {
+  @BeforeEach
+  override fun setUp(testInfo: TestInfo) {
+    super.setUp(testInfo)
+    configureByText("\n")
+  }
+
+  @Test
+  fun `test acos with Number`() {
+    assertCommandOutput("echo acos(0)", "1.570796")
+    assertCommandOutput("echo acos(-1) acos(0) acos(1)", "3.141593 1.570796 0.0")
+  }
+
+  @Test
+  fun `test acos with Float`() {
+    assertCommandOutput("echo acos(-0.5)", "2.094395")
+    assertCommandOutput("echo acos(-1.0) acos(0.0) acos(1.0)", "3.141593 1.570796 0.0")
+  }
+
+  @Test
+  fun `test acos with value greater than 1 returns nan`() {
+    assertCommandOutput("echo acos(1.1)", "nan")
+  }
+
+  @Test
+  fun `test acos with value less than -1 returns nan`() {
+    assertCommandOutput("echo acos(-1.1)", "nan")
+  }
+
+  @Test
+  fun `test acos with string causes errors`() {
+    enterCommand("echo acos('1.0')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test acos with invalid string causes errors`() {
+    enterCommand("echo acos('cheese')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test acos with list causes errors`() {
+    enterCommand("echo acos([1.0])")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test acos with dictionary causes errors`() {
+    enterCommand("echo acos({1: 1.0})")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+}
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AsinFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AsinFunctionTest.kt
new file mode 100644
index 000000000..b803e121d
--- /dev/null
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AsinFunctionTest.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package org.jetbrains.plugins.ideavim.ex.implementation.functions.floatFunctions
+
+import org.jetbrains.plugins.ideavim.VimTestCase
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInfo
+
+class AsinFunctionTest : VimTestCase() {
+  @BeforeEach
+  override fun setUp(testInfo: TestInfo) {
+    super.setUp(testInfo)
+    configureByText("\n")
+  }
+
+  @Test
+  fun `test asin with Number`() {
+    assertCommandOutput("echo asin(1)", "1.570796")
+    assertCommandOutput("echo asin(-1) asin(0) asin(1)", "-1.570796 0.0 1.570796")
+  }
+
+  @Test
+  fun `test asin with Float`() {
+    assertCommandOutput("echo asin(1.0)", "1.570796")
+    assertCommandOutput("echo asin(0.8) asin(-0.5)", "0.927295 -0.523599")
+  }
+
+  @Test
+  fun `test asin with value greater than 1 returns nan`() {
+    assertCommandOutput("echo asin(1.1)", "nan")
+  }
+
+  @Test
+  fun `test asin with value less than -1 returns nan`() {
+    assertCommandOutput("echo asin(-1.1)", "nan")
+  }
+
+  @Test
+  fun `test asin with string causes errors`() {
+    enterCommand("echo asin('1.0')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test asin with invalid string causes errors`() {
+    enterCommand("echo asin('cheese')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test asin with list causes errors`() {
+    enterCommand("echo asin([1.0])")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test asin with dictionary causes errors`() {
+    enterCommand("echo asin({1: 1.0})")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+}
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/Atan2FunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/Atan2FunctionTest.kt
new file mode 100644
index 000000000..a600fe1f7
--- /dev/null
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/Atan2FunctionTest.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package org.jetbrains.plugins.ideavim.ex.implementation.functions.floatFunctions
+
+import org.jetbrains.plugins.ideavim.VimTestCase
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInfo
+
+class Atan2FunctionTest : VimTestCase() {
+  @BeforeEach
+  override fun setUp(testInfo: TestInfo) {
+    super.setUp(testInfo)
+    configureByText("\n")
+  }
+
+  @Test
+  fun `test atan2 with Number`() {
+    assertCommandOutput("echo atan2(100, 100)", "0.785398")
+    assertCommandOutput("echo atan2(-1, 1) atan2(1, -1)", "-0.785398 2.356194")
+  }
+
+  @Test
+  fun `test atan2 with Float`() {
+    assertCommandOutput("echo atan2(-1.0, 1.0) atan2(1.0, -1.0)", "-0.785398 2.356194")
+  }
+
+  @Test
+  fun `test atan2 with string causes errors`() {
+    enterCommand("echo atan2('1.0', 1.0)")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test atan2 with string causes errors 2`() {
+    enterCommand("echo atan2(1.0, '1.0')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test atan2 with invalid string causes errors`() {
+    enterCommand("echo atan2('cheese', 1.0)")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+  @Test
+
+  fun `test atan2 with invalid string causes errors 2`() {
+    enterCommand("echo atan2(1.0, 'cheese')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test atan2 with list causes errors`() {
+    enterCommand("echo atan2([1.0], 1.0)")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test atan2 with list causes errors 2`() {
+    enterCommand("echo atan2(1.0, [1.0])")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test atan2 with dictionary causes errors`() {
+    enterCommand("echo atan2({1: 1.0}, 1.0)")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test atan2 with dictionary causes errors 2`() {
+    enterCommand("echo atan2(1.0, {1: 1.0})")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+}
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AtanFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AtanFunctionTest.kt
new file mode 100644
index 000000000..47b263310
--- /dev/null
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/AtanFunctionTest.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package org.jetbrains.plugins.ideavim.ex.implementation.functions.floatFunctions
+
+import org.jetbrains.plugins.ideavim.VimTestCase
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInfo
+
+class AtanFunctionTest : VimTestCase() {
+  @BeforeEach
+  override fun setUp(testInfo: TestInfo) {
+    super.setUp(testInfo)
+    configureByText("\n")
+  }
+
+  @Test
+  fun `test atan with Number`() {
+    assertCommandOutput("echo atan(100)", "1.560797")
+    assertCommandOutput("echo atan(0) atan(1)", "0.0 0.785398")
+  }
+
+  @Test
+  fun `test atan with Float`() {
+    assertCommandOutput("echo atan(100.0) atan(-4.01)", "1.560797 -1.326405")
+  }
+
+  @Test
+  fun `test atan with string causes errors`() {
+    enterCommand("echo atan('1.0')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test atan with invalid string causes errors`() {
+    enterCommand("echo atan('cheese')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test atan with list causes errors`() {
+    enterCommand("echo atan([1.0])")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test atan with dictionary causes errors`() {
+    enterCommand("echo atan({1: 1.0})")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+}
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/CosFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/CosFunctionTest.kt
new file mode 100644
index 000000000..2ebe0357d
--- /dev/null
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/CosFunctionTest.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package org.jetbrains.plugins.ideavim.ex.implementation.functions.floatFunctions
+
+import org.jetbrains.plugins.ideavim.VimTestCase
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInfo
+
+class CosFunctionTest : VimTestCase() {
+  @BeforeEach
+  override fun setUp(testInfo: TestInfo) {
+    super.setUp(testInfo)
+    configureByText("\n")
+  }
+
+  @Test
+  fun `test cos with Number`() {
+    assertCommandOutput("echo cos(100)", "0.862319")
+    assertCommandOutput("echo cos(0) cos(1)", "1.0 0.540302")
+  }
+
+  @Test
+  fun `test cos with Float`() {
+    assertCommandOutput("echo cos(-4.01)", "-0.646043")
+    assertCommandOutput("echo cos(0.0) cos(1.0)", "1.0 0.540302")
+  }
+
+  @Test
+  fun `test cos with string causes errors`() {
+    enterCommand("echo cos('1.0')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test cos with invalid string causes errors`() {
+    enterCommand("echo cos('cheese')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test cos with list causes errors`() {
+    enterCommand("echo cos([1.0])")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test cos with dictionary causes errors`() {
+    enterCommand("echo cos({1: 1.0})")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+}
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/CoshFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/CoshFunctionTest.kt
new file mode 100644
index 000000000..1598f6ab7
--- /dev/null
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/CoshFunctionTest.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package org.jetbrains.plugins.ideavim.ex.implementation.functions.floatFunctions
+
+import org.jetbrains.plugins.ideavim.VimTestCase
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInfo
+
+class CoshFunctionTest : VimTestCase() {
+  @BeforeEach
+  override fun setUp(testInfo: TestInfo) {
+    super.setUp(testInfo)
+    configureByText("\n")
+  }
+
+  @Test
+  fun `test cosh with Number`() {
+    assertCommandOutput("echo cosh(100)", "1.344059e43")
+    assertCommandOutput("echo cosh(0) cosh(1)", "1.0 1.543081")
+  }
+
+  @Test
+  fun `test cosh with Float`() {
+    // The Vim docs show cosh(-0.5) == -1.127626, but the function returns the positive value...
+    // We are matching Vim's actual behaviour here
+    assertCommandOutput("echo cosh(0.5) cosh(-0.5)", "1.127626 1.127626")
+  }
+
+  @Test
+  fun `test cosh with string causes errors`() {
+    enterCommand("echo cosh('1.0')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test cosh with invalid string causes errors`() {
+    enterCommand("echo cosh('cheese')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test cosh with list causes errors`() {
+    enterCommand("echo cosh([1.0])")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test cosh with dictionary causes errors`() {
+    enterCommand("echo cosh({1: 1.0})")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+}
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/SinFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/SinFunctionTest.kt
index 2a0fc1a08..ffc43959d 100644
--- a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/SinFunctionTest.kt
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/SinFunctionTest.kt
@@ -21,7 +21,42 @@ class SinFunctionTest : VimTestCase() {
   }
 
   @Test
-  fun `test sin`() {
+  fun `test sin with Number`() {
+    assertCommandOutput("echo sin(100)", "-0.506366")
     assertCommandOutput("echo sin(0) sin(1)", "0.0 0.841471")
   }
+
+  @Test
+  fun `test sin with Float`() {
+    assertCommandOutput("echo sin(-4.01)", "0.763301")
+    assertCommandOutput("echo sin(0.0) sin(1.0)", "0.0 0.841471")
+  }
+
+  @Test
+  fun `test sin with string causes errors`() {
+    enterCommand("echo sin('1.0')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test sin with invalid string causes errors`() {
+    enterCommand("echo sin('cheese')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test sin with list causes errors`() {
+    enterCommand("echo sin([1.0])")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test sin with dictionary causes errors`() {
+    enterCommand("echo sin({1: 1.0})")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
 }
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/SinhFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/SinhFunctionTest.kt
new file mode 100644
index 000000000..9f64d67df
--- /dev/null
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/SinhFunctionTest.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package org.jetbrains.plugins.ideavim.ex.implementation.functions.floatFunctions
+
+import org.jetbrains.plugins.ideavim.VimTestCase
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInfo
+
+class SinhFunctionTest : VimTestCase() {
+  @BeforeEach
+  override fun setUp(testInfo: TestInfo) {
+    super.setUp(testInfo)
+    configureByText("\n")
+  }
+
+  @Test
+  fun `test sinh with Number`() {
+    assertCommandOutput("echo sinh(100)", "1.344059e43")
+    assertCommandOutput("echo sinh(0) sinh(1)", "0.0 1.175201")
+  }
+
+  @Test
+  fun `test sinh with Float`() {
+    assertCommandOutput("echo sinh(0.5) sinh(-0.9)", "0.521095 -1.026517")
+  }
+
+  @Test
+  fun `test sinh with string causes errors`() {
+    enterCommand("echo sinh('1.0')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test sinh with invalid string causes errors`() {
+    enterCommand("echo sinh('cheese')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test sinh with list causes errors`() {
+    enterCommand("echo sinh([1.0])")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test sinh with dictionary causes errors`() {
+    enterCommand("echo sinh({1: 1.0})")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+}
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/TanFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/TanFunctionTest.kt
new file mode 100644
index 000000000..346fcc873
--- /dev/null
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/TanFunctionTest.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package org.jetbrains.plugins.ideavim.ex.implementation.functions.floatFunctions
+
+import org.jetbrains.plugins.ideavim.VimTestCase
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInfo
+
+class TanFunctionTest : VimTestCase() {
+  @BeforeEach
+  override fun setUp(testInfo: TestInfo) {
+    super.setUp(testInfo)
+    configureByText("\n")
+  }
+
+  @Test
+  fun `test tan with Number`() {
+    assertCommandOutput("echo tan(10)", "0.648361")
+    assertCommandOutput("echo tan(0) tan(1)", "0.0 1.557408")
+  }
+
+  @Test
+  fun `test tan with Float`() {
+    assertCommandOutput("echo tan(-4.01)", "-1.181502")
+    assertCommandOutput("echo tan(0.0) tan(1.0)", "0.0 1.557408")
+  }
+
+  @Test
+  fun `test tan with string causes errors`() {
+    enterCommand("echo tan('1.0')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test tan with invalid string causes errors`() {
+    enterCommand("echo tan('cheese')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test tan with list causes errors`() {
+    enterCommand("echo tan([1.0])")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test tan with dictionary causes errors`() {
+    enterCommand("echo tan({1: 1.0})")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+}
diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/TanhFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/TanhFunctionTest.kt
new file mode 100644
index 000000000..788d2b972
--- /dev/null
+++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/TanhFunctionTest.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package org.jetbrains.plugins.ideavim.ex.implementation.functions.floatFunctions
+
+import org.jetbrains.plugins.ideavim.VimTestCase
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.TestInfo
+
+class TanhFunctionTest : VimTestCase() {
+  @BeforeEach
+  override fun setUp(testInfo: TestInfo) {
+    super.setUp(testInfo)
+    configureByText("\n")
+  }
+
+  @Test
+  fun `test tanh with Number`() {
+    assertCommandOutput("echo tanh(100)", "1.0")
+    assertCommandOutput("echo tanh(0) tanh(1)", "0.0 0.761594")
+  }
+
+  @Test
+  fun `test tanh with Float`() {
+    assertCommandOutput("echo tanh(0.5) tanh(-1.0)", "0.462117 -0.761594")
+  }
+
+  @Test
+  fun `test tanh with string causes errors`() {
+    enterCommand("echo tanh('1.0')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test tanh with invalid string causes errors`() {
+    enterCommand("echo tanh('cheese')")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test tanh with list causes errors`() {
+    enterCommand("echo tanh([1.0])")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+
+  @Test
+  fun `test tanh with dictionary causes errors`() {
+    enterCommand("echo tanh({1: 1.0})")
+    assertPluginError(true)
+    assertPluginErrorMessageContains("E808: Number or Float required")
+  }
+}
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/datatypes/VimFloat.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/datatypes/VimFloat.kt
index 2c56a54d3..17009cfc7 100644
--- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/datatypes/VimFloat.kt
+++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/datatypes/VimFloat.kt
@@ -9,8 +9,8 @@
 package com.maddyhome.idea.vim.vimscript.model.datatypes
 
 import com.maddyhome.idea.vim.ex.ExException
-import java.math.BigDecimal
-import java.math.RoundingMode
+import java.text.DecimalFormat
+import kotlin.math.abs
 
 data class VimFloat(val value: Double) : VimDataType() {
 
@@ -27,8 +27,15 @@ data class VimFloat(val value: Double) : VimDataType() {
   }
 
   override fun toString(): String {
-    val bigDecimal = BigDecimal(value).setScale(6, RoundingMode.HALF_UP)
-    return bigDecimal.toDouble().toString()
+    if (value.isNaN()) return "nan"
+    return if (abs(value) >= 1e6 || (abs(value) < 1e-3 && value != 0.0)) {
+      val formatter = DecimalFormat("0.0#####E0")
+      formatter.decimalFormatSymbols = formatter.decimalFormatSymbols.apply { exponentSeparator = "e" }
+      formatter.format(value)
+    }
+    else {
+      DecimalFormat("0.0#####").format(value)
+    }
   }
 
   override fun deepCopy(level: Int): VimFloat {
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/FloatFunctionHandlerBase.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/FloatFunctionHandlerBase.kt
new file mode 100644
index 000000000..c6ee93331
--- /dev/null
+++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/FloatFunctionHandlerBase.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions
+
+import com.maddyhome.idea.vim.api.ExecutionContext
+import com.maddyhome.idea.vim.api.VimEditor
+import com.maddyhome.idea.vim.ex.exExceptionMessage
+import com.maddyhome.idea.vim.vimscript.model.VimLContext
+import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
+import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFloat
+import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
+import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
+import com.maddyhome.idea.vim.vimscript.model.functions.FunctionHandler
+
+internal abstract class UnaryFloatFunctionHandlerBase : FunctionHandler() {
+  override val minimumNumberOfArguments = 1
+  override val maximumNumberOfArguments = 1
+
+  override fun doFunction(
+    argumentValues: List<Expression>,
+    editor: VimEditor,
+    context: ExecutionContext,
+    vimContext: VimLContext,
+  ): VimDataType {
+    val argument = argumentValues[0].evaluate(editor, context, vimContext)
+    if (argument !is VimFloat && argument !is VimInt) {
+      throw exExceptionMessage("E808")  // E808: Number or Float required
+    }
+    return VimFloat(invoke(argument.asDouble()))
+  }
+
+  protected abstract fun invoke(argument: Double): Double
+}
+
+internal abstract class BinaryFloatFunctionHandlerBase : FunctionHandler() {
+  override val minimumNumberOfArguments = 2
+  override val maximumNumberOfArguments = 2
+
+  override fun doFunction(
+    argumentValues: List<Expression>,
+    editor: VimEditor,
+    context: ExecutionContext,
+    vimContext: VimLContext,
+  ): VimDataType {
+    val arg1 = argumentValues[0].evaluate(editor, context, vimContext)
+    val arg2 = argumentValues[1].evaluate(editor, context, vimContext)
+    if ((arg1 !is VimFloat && arg1 !is VimInt) || (arg2 !is VimFloat && arg2 !is VimInt)) {
+      throw exExceptionMessage("E808")  // E808: Number or Float required
+    }
+    return VimFloat(invoke(arg1.asDouble(), arg2.asDouble()))
+  }
+
+  protected abstract fun invoke(arg1: Double, arg2: Double): Double
+}
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/HyperbolicFunctionHandlers.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/HyperbolicFunctionHandlers.kt
new file mode 100644
index 000000000..0c24770af
--- /dev/null
+++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/HyperbolicFunctionHandlers.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions
+
+import com.intellij.vim.annotations.VimscriptFunction
+import kotlin.math.cosh
+import kotlin.math.sinh
+import kotlin.math.tanh
+
+@VimscriptFunction(name = "cosh")
+internal class CoshFunctionHandler : UnaryFloatFunctionHandlerBase() {
+  override fun invoke(argument: Double) = cosh(argument)
+}
+
+@VimscriptFunction(name = "sinh")
+internal class SinhFunctionHandler : UnaryFloatFunctionHandlerBase() {
+  override fun invoke(argument: Double) = sinh(argument)
+}
+
+@VimscriptFunction(name = "tanh")
+internal class TanhFunctionHandler : UnaryFloatFunctionHandlerBase() {
+  override fun invoke(argument: Double) = tanh(argument)
+}
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/SinFunctionHandler.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/SinFunctionHandler.kt
deleted file mode 100644
index f9f1b723b..000000000
--- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/SinFunctionHandler.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2003-2025 The IdeaVim authors
- *
- * Use of this source code is governed by an MIT-style
- * license that can be found in the LICENSE.txt file or at
- * https://opensource.org/licenses/MIT.
- */
-
-package com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions
-
-import com.intellij.vim.annotations.VimscriptFunction
-import com.maddyhome.idea.vim.api.ExecutionContext
-import com.maddyhome.idea.vim.api.VimEditor
-import com.maddyhome.idea.vim.vimscript.model.VimLContext
-import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
-import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFloat
-import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
-import com.maddyhome.idea.vim.vimscript.model.functions.FunctionHandler
-import kotlin.math.sin
-
-@VimscriptFunction(name = "sin")
-internal class SinFunctionHandler : FunctionHandler() {
-  override val minimumNumberOfArguments = 1
-  override val maximumNumberOfArguments = 1
-
-  override fun doFunction(
-    argumentValues: List<Expression>,
-    editor: VimEditor,
-    context: ExecutionContext,
-    vimContext: VimLContext,
-  ): VimDataType {
-    val argument = argumentValues[0].evaluate(editor, context, vimContext)
-    return VimFloat(sin(argument.asDouble()))
-  }
-}
diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/TrigonometricFunctionHandlers.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/TrigonometricFunctionHandlers.kt
new file mode 100644
index 000000000..06bdb5f7d
--- /dev/null
+++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/TrigonometricFunctionHandlers.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2003-2025 The IdeaVim authors
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE.txt file or at
+ * https://opensource.org/licenses/MIT.
+ */
+
+package com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions
+
+import com.intellij.vim.annotations.VimscriptFunction
+import kotlin.math.acos
+import kotlin.math.asin
+import kotlin.math.atan
+import kotlin.math.atan2
+import kotlin.math.cos
+import kotlin.math.sin
+import kotlin.math.tan
+
+@VimscriptFunction(name = "acos")
+internal class AcosFunctionHandler : UnaryFloatFunctionHandlerBase() {
+  override fun invoke(argument: Double) = acos(argument)
+}
+
+@VimscriptFunction(name = "asin")
+internal class AsinFunctionHandler : UnaryFloatFunctionHandlerBase() {
+  override fun invoke(argument: Double) = asin(argument)
+}
+
+@VimscriptFunction(name = "atan")
+internal class AtanFunctionHandler : UnaryFloatFunctionHandlerBase() {
+  override fun invoke(argument: Double) = atan(argument)
+}
+
+@VimscriptFunction(name = "atan2")
+internal class Atan2FunctionHandler : BinaryFloatFunctionHandlerBase() {
+  override fun invoke(arg1: Double, arg2: Double) = atan2(arg1, arg2)
+}
+
+@VimscriptFunction(name = "cos")
+internal class CosFunctionHandler : UnaryFloatFunctionHandlerBase() {
+  override fun invoke(argument: Double) = cos(argument)
+}
+
+@VimscriptFunction(name = "sin")
+internal class SinFunctionHandler : UnaryFloatFunctionHandlerBase() {
+  override fun invoke(argument: Double) = sin(argument)
+}
+
+@VimscriptFunction(name = "tan")
+internal class TanFunctionHandler : UnaryFloatFunctionHandlerBase() {
+  override fun invoke(argument: Double) = tan(argument)
+}
diff --git a/vim-engine/src/main/resources/ksp-generated/engine_vimscript_functions.json b/vim-engine/src/main/resources/ksp-generated/engine_vimscript_functions.json
index dc0121730..f88276cb6 100644
--- a/vim-engine/src/main/resources/ksp-generated/engine_vimscript_functions.json
+++ b/vim-engine/src/main/resources/ksp-generated/engine_vimscript_functions.json
@@ -1,7 +1,13 @@
 {
     "abs": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.AbsFunctionHandler",
+    "acos": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.AcosFunctionHandler",
     "and": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.bitwiseFunctions.AndFunctionHandler",
+    "asin": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.AsinFunctionHandler",
+    "atan": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.AtanFunctionHandler",
+    "atan2": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.Atan2FunctionHandler",
     "col": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.cursorFunctions.ColFunctionHandler",
+    "cos": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.CosFunctionHandler",
+    "cosh": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.CoshFunctionHandler",
     "empty": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.EmptyFunctionHandler",
     "escape": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.stringFunctions.EscapeFunctionHandler",
     "exists": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.variousFunctions.ExistsFunctionHandler",
@@ -15,9 +21,12 @@
     "line": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.cursorFunctions.LineFunctionHandler",
     "or": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.bitwiseFunctions.OrFunctionHandler",
     "sin": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.SinFunctionHandler",
+    "sinh": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.SinhFunctionHandler",
     "split": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.listFunctions.SplitFunctionHandler",
     "submatch": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.stringFunctions.SubmatchFunctionHandler",
+    "tan": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.TanFunctionHandler",
+    "tanh": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.TanhFunctionHandler",
     "tolower": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.stringFunctions.TolowerFunctionHandler",
     "toupper": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.stringFunctions.ToupperFunctionHandler",
     "xor": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.bitwiseFunctions.XorFunctionHandler"
-}
\ No newline at end of file
+}